Опытные гуру PHP и MySQL помогите.Сделал скрипт перетаскивания данных из txt файла в базу данных Mysql для сайта.
С помощью команды$result = mysql_query("INSERT INTO prise1 (id, order_date, id_1c, name, cost, cod_prod, quantity, group_1c, name1, name2, name3, producer, description1, description2, description3, description4, description5, description6, description7) VALUES ('$line', '$order_date', '$str[0]', '$str[1]', '$str[2]', '$str[3]', '$str[4]', '$str[5]', '$str[6]', '$str[7]', '$str[8]', '$str[9]', '$str[10]', '$str[11]', '$str[12]', '$str[13]', '$str[14]', '$str[15]', '$str[16]');");
данные из массива (строки) переносятся в базу mysql и всё хорошо, но возникла загвоздка, если строка такая3 CD-R диск Mirex "Цифровой фотоальбом" 700Mb 48x slim 15р. 7096 0 АКСЕССУАРЫ CD-R и RW Диск Mirex CD-R Россия "Цифровой фотоальбом" 700Mb 48x slim
т.е. любая из '$str[ ]' имеет внутри кавычку(двойную или одинарную) -> по команде INSERT данные строки не заносятся, возникает ошибка.
Как мне сделать так чтобы данные заносились и с кавычками тоже?
Посмотрите функцию mysql_escape_string()Кроме этого замечу, что, возможно, БД плохо спроектирована. Наличие полей вроде name1, name2, name3 и description1, description2, description3, ... со временем приводит к появлению "дырявых" таблиц и не рациональному использованию
>Посмотрите функцию mysql_escape_string()Так же посмотрите про директиву magic_quotes_gpc
>Посмотрите функцию mysql_escape_string()
>
>Кроме этого замечу, что, возможно, БД плохо спроектирована. Наличие полей вроде
>name1, name2, name3 и description1, description2, description3, ... со временем приводит
>к появлению "дырявых" таблиц и не рациональному использованиюА можно сразу по подробнее? Структура таблици:
+--------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+-------------------+-----------------------------+
| id | mediumint(8) | NO | PRI | NULL | auto_increment |
| order_date | varchar(10) | NO | | NULL | |
| last_date | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| id_1c | varchar(5) | NO | | NULL | |
| name | varchar(256) | NO | | NULL | |
| cost | varchar(10) | NO | | NULL | |
| cod_prod | varchar(20) | NO | | NULL | |
| quantity | varchar(20) | NO | | NULL | |
| group_1c | varchar(20) | NO | | NULL | |
| name1 | varchar(50) | NO | | NULL | |
| name2 | varchar(50) | NO | | NULL | |
| name3 | varchar(50) | NO | | NULL | |
| producer | varchar(128) | NO | | NULL | |
| description1 | varchar(999) | NO | | NULL | |
| description2 | varchar(999) | NO | | NULL | |
| description3 | varchar(999) | NO | | NULL | |
| description4 | varchar(999) | NO | | NULL | |
| description5 | varchar(999) | NO | | NULL | |
| description6 | varchar(999) | NO | | NULL | |
| description7 | varchar(999) | NO | | NULL | |
+--------------+--------------+------+-----+-------------------+-----------------------------+
>А можно сразу по подробнее? Структура таблици:
>Я вижу поля name,name1,name2,name3 и тоже самое с description1. Если они ВСЕ и КАЖДЫЙ раз полностью заполняются, то тогда все ОК. Если они запроектированы на всякий случай (вдруг может надо будет), то лучше создать еще две таблицы вида names и descriptions и связать их с основной таблицей. Еще для полей description, скорее всего, следует использопать тип text, а не varchar.
Пишите на почту если что-то не понятно - объясню
Спасибо за ответ.
Вопрос только один как связать несколько таблиц? по id?
И как это сделать более профессионально?
Ну это я загнул, но как это сделать чтобы работало быстрее?
>Спасибо за ответ.
>Вопрос только один как связать несколько таблиц? по id?
>И как это сделать более профессионально?
>Ну это я загнул, но как это сделать чтобы работало быстрее?Используйте JOIN
http://www.mysql.ru/docs/man/JOIN.html
Сеня отзовись
>Спасибо за ответ.
>Вопрос только один как связать несколько таблиц? по id?
>И как это сделать более профессионально?
>Ну это я загнул, но как это сделать чтобы работало быстрее?Чтобы правильно запроектировать БД нужно знать характер заносимых данных. Если (логически) каждому одному name ВСЕГДА будет соответствовать один description, то можно создать одну дополнительную таблицу с полями что-то вроде id, parent_id, name, description. Если количество полей name и description не соответствуют друг другу то нужно создавать две дополнительные таблицы.
Потом в основной таблице получаем запись и, зная ее id, получаете name и/или description по parent_id в зависимости от того что нужно в данный момент.
Но чтобы точно сделать правильно нужно знать характер данных.
Вы уж простите, но не смог пройти мимо. И дабы не плодить ответов, пару ваших постов объединил в один. А теперь позанудствую.
У меня складывается ощущение, что вы и сами не сможете правильно "запроектировать" базу. И еще людей в заблуждение вводите. Чтобы спроектировать грамотную БД не надо знать характер данных, они вообще могут быть любые. Главное данные систематизировать, вывести связи (1:1, 1:М, это примерно сюда) и понять как эти данные будут использоваться (как/куда будут выводиться, как обновляться, как дополняться, etc, etc, etc). На серьезных БД не лишним будет учесть и используемую СУБД.
>Я вижу поля name,name1,name2,name3 и тоже самое с description1.
>Если они ВСЕ и КАЖДЫЙ раз полностью заполняются, то тогда все ОК.Не могу понять логику вашего высказывания. Почему не может быть ОК, если эти поля заполняются не все и не каждый раз? Ошибка проектирования (и то, с точки зрения дальнейшей поддержки БД живыми человеками) здесь может заключаться только в некорректном именовании столбцов таблицы - сменится админ БД и будет неделю выяснять что именно хранится в name1, name2, name3...
>Если они запроектированы на всякий случай (вдруг может надо будет), то лучше создать еще две таблицы вида names и descriptions и связать их с основной таблицей.Очень спорно. А если "вдруг" вот уже как пару лет не настает? А join-ы до сих пор с пустой таблицей работают. А зачем join-ы? А вдруг в тех двух таблицах внезапно появятся данные... Обычно, если "вдруг" настает и нужно хранить доп. данные, делают ALTER TABLE или создают новую таблицу. Да и выделять одному свойству сущности целую таблицу...
>Если (логически) каждому
>одному name ВСЕГДА будет соответствовать один description, то можно создать одну
>дополнительную таблицу с полями что-то вроде id, parent_id, name, description. Если
>количество полей name и description не соответствуют друг другу то нужно
>создавать две дополнительные таблицы.
>Потом в основной таблице получаем запись и, зная ее id, получаете name
>и/или description по parent_id в зависимости от того что нужно в
>данный момент.А вот тут я завис на долго. Хорошо, что кошка отвлекла - она у меня как watchdog таймер, не дала зациклиться :))
Может я примерно и понял замысел тех советов, но не понял их смысл. Если вы избавляетесь от лишних полей в основной таблице, зачем поле id в дополнительной? Оно вам там ничего уникально не сыдентифицирует и с ним вы ничего осмысленного не получите. Если в основной таблице вашими методами вы избавились от name1, name2, name3 и таких же description, то напр, запрос вида "обнови второе имя у сущности с id=999" выполнить не получится. И зачем мне еще кучу join-ов с запросом типа "хочу все знать о сущности с id=999"? А если в будущем добавятся поля subname1, subname2, то мне нужно будет перелопатить все исходники и поменять такой запрос с учетом новых полей?
Если уж и делать по вашему замыслу, то нужна только одна таблица вида id, type, value с записями вида 999,'name2','второе имя'; 732,'descr1','описание 1'. Но это уже похоже на модель EAV со всеми вытекающими...>Потом в основной таблице получаем запись и, зная ее id, получаете name и/или description по parent_id в зависимости от того что нужно в данный момент.
И вы тоже одно и то же именуете по-разному? :) А ведь это в некой степени ошибка проектировки. Любой primary key и соответствующий ему foreign key хранят _одно и то же_. Зачем же тогда им давать разные имена? К тому же, это поможет сократить sql-запрос, его читаемость и "понимаемость" новыми программерами или админами БД, да и вообще кошернее смотреться будет: вместо ... JOIN b on (a.id=b.parent_id) вы напишете ... JOIN b using(id). А те субд, что умеют NATURAL JOIN, так вообще сказка: ... NATURAL JOIN b. Согласитесь, удобнее.
По большому счету, это мое утверждение спорно, но лишь в том случае, когда на свет вылазят защитники принципа "имя таблицы не должно дублироваться в именах столбцов", напр. "столбцы с айди в любой таблице должны называться id". Определенный смысл в этом есть ("..where product.cost < package.cost.."), но такой принцип не канает в случаях, когда в таблице есть связь 1:1, напр. в таблице "сотрудник" придется заводить "отдел_id", т.к. поле "id" - это PK самой таблицы.
>Наличие полей вроде name1, name2, name3 и description1, description2, description3, ...
>со временем приводит к появлению "дырявых" таблиц и не рациональному использованиюНаличие таких полей ни о чем однозначно не говорит. Оно может как бы намекать нам на то, что создатель БД новичок, либо ему было лень дать нормальные имена, либо что таблица будет использоваться как тестовая минут -дцать, а потом ее дропнут.
Ну а если вы тотальный рационализатор и стремитесь к организации БД так, чтобы любая новая запись в таблицу заполняла _все_ поля, то... фиговый вы "запроектировщик" баз без "дырявых таблиц".
Кстати, а вы NULL считаете значением?)зы. Сорри, если обидел. Настроение чего-то какое-то такое...))
-----
А это топикстартеру:
>>Вопрос только один как связать несколько таблиц? по id?join-ами. по одинаковым полям, не обязательно (но как правило) id.
можно еще select * from a, b where a.id = b.id;>>И как это сделать более профессионально?
join-ами
>>Ну это я загнул, но как это сделать чтобы работало быстрее?
Можно заюзать индексы. Можно провести денормализацию или наоборот, привести данные к какой-нибудь нормальной форме (это термин такой, "нормальная форма").
Но оно вам надо? У вас уже такие масштабы данных, что впору задумываться о скорости?
>Чтобы спроектировать грамотную БД
>не надо знать характер данных, они вообще могут быть любые. Главное
>данные систематизировать, вывести связи (1:1, 1:М, это примерно сюда) и понятьВы сами себе противоречите. Как будете выводить связи если не знаете что за данные в БД?
Собственно за отношения (1:1, 1:М) я и говорил.>Не могу понять логику вашего высказывания. Почему не может быть ОК, если
>эти поля заполняются не все и не каждый раз? Ошибка проектирования
>(и то, с точки зрения дальнейшей поддержки БД живыми человеками) здесь
>может заключаться только в некорректном именовании столбцов таблицы - сменится админ
>БД и будет неделю выяснять что именно хранится в name1, name2,
>name3...Логика тут одна - чем меньше пустых полей тем лучьше. Но здесь, главное преимущество, что снимается ограничение на количество дополнительных полей. Хочешь вставляй 1 поле, хочешь 6 или 106. В исходном варианте не больше 6.
>Очень спорно. А если "вдруг" вот уже как пару лет не настает?
>А join-ы до сих пор с пустой таблицей работают. А зачем
>join-ы? А вдруг в тех двух таблицах внезапно появятся данные... Обычно,
>если "вдруг" настает и нужно хранить доп. данные, делают ALTER TABLE
>или создают новую таблицу. Да и выделять одному свойству сущности целую
>таблицу...Нступает "вдруг", вы делаете ALTER TABLE и добываляете еще поле (или несколько). Потом еще "вдруг", опять ALTER TABLE и таблица становится еще шире. Так может сразу выделить в отдельную таблицу? Почему бы и нет. К тому же после каждого ALTER TABLE придется корректировать скрипты.
>[оверквотинг удален]
>Может я примерно и понял замысел тех советов, но не понял их
>смысл. Если вы избавляетесь от лишних полей в основной таблице, зачем
>поле id в дополнительной? Оно вам там ничего уникально не сыдентифицирует
>и с ним вы ничего осмысленного не получите. Если в основной
>таблице вашими методами вы избавились от name1, name2, name3 и таких
>же description, то напр, запрос вида "обнови второе имя у сущности
>с id=999" выполнить не получится. И зачем мне еще кучу join-ов
>с запросом типа "хочу все знать о сущности с id=999"? А
>если в будущем добавятся поля subname1, subname2, то мне нужно будет
>перелопатить все исходники и поменять такой запрос с учетом новых полей?Избавиться от лишних полей не самоцель. В исходной таблице идут name1, name2, name3. Вы точно знаете что их порядок не имеет значение? Поля id нужны для сортировки. Без них (если нужно) в точном порядке вывести значения будет нельзя. А как внести правку? А удалить?
А на счет скоращения количества полей, то согласитесь, что довольно существенно поменять хотя бы одно поле varchar(999) на одно int.
>[оверквотинг удален]
>вообще кошернее смотреться будет: вместо ... JOIN b on (a.id=b.parent_id) вы
>напишете ... JOIN b using(id). А те субд, что умеют NATURAL
>JOIN, так вообще сказка: ... NATURAL JOIN b. Согласитесь, удобнее.
>По большому счету, это мое утверждение спорно, но лишь в том случае,
>когда на свет вылазят защитники принципа "имя таблицы не должно дублироваться
>в именах столбцов", напр. "столбцы с айди в любой таблице должны
>называться id". Определенный смысл в этом есть ("..where product.cost < package.cost.."),
>но такой принцип не канает в случаях, когда в таблице есть
>связь 1:1, напр. в таблице "сотрудник" придется заводить "отдел_id", т.к. поле
>"id" - это PK самой таблицы.Соглашусь что утверждение спорно :)
Дело привычки по большому счету
>Наличие таких полей ни о чем однозначно не говорит. Оно может как
>бы намекать нам на то, что создатель БД новичок, либо ему
>было лень дать нормальные имена, либо что таблица будет использоваться как
>тестовая минут -дцать, а потом ее дропнут.А однозначно я ничего не утверждал. Более того - говорил что нужно знать что будет храниться. Если там будут храниться длина/ширина/высота и т.п. и называться типа name1, name2,... потому что "ему было лень дать нормальные имена" то ничего менять не надо.
>Ну а если вы тотальный рационализатор и стремитесь к организации БД так,
>чтобы любая новая запись в таблицу заполняла _все_ поля, то... фиговый
>вы "запроектировщик" баз без "дырявых таблиц".
>Кстати, а вы NULL считаете значением?)Я не " тотальный рационализатор", но иногда вижу как лучше. И не надо кидаться в крайности обзывая меня "фиговый вы "запроектировщик". Фраза "дырявые таблицы" придумана не мной и, очевидно, не просто так.
>зы. Сорри, если обидел. Настроение чего-то какое-то такое...))А! Так это чтобы дух отвести?
Кошке привет!
>>данные систематизировать, вывести связи (1:1, 1:М, это примерно сюда) и понять
>
>Вы сами себе противоречите. Как будете выводить связи если не знаете что
>за данные в БД?Я как раз написал в том порядке, в котором надо действовать. Вывод связей - на втором месте, так что на этот момент данные уже у нас есть.
Но говоря про характер, это скорее похоже на вопрос админа "чего хранить будем" на задачу шефа "сделай мне БД ко вчера". Это вообще нулевой этап. Может быть данные такие будут, что их эффективно можно хранить в нереляционной БД. А там свои понятия могут быть, отличные от "сущность", "связь" и т.д.
>>Почему не может быть ОК, если эти поля заполняются не все и не каждый раз?
>Логика тут одна - чем меньше пустых полей тем лучьше. Но здесь,
>главное преимущество, что снимается ограничение на количество дополнительных полей.
> Хочешь вставляй 1 поле, хочешь 6 или 106. В исходном варианте не больше 6.Эмм, может быть мы про разные типы СУБД говорим? Я про реляционные.
Почему чем меньше пустых значений, тем лучше? Лучше в каком плане? По скорости выборки? Планировщик лучше работает? Ну постройте индекс (если он будет полезен) по соответствующему полю...
Если вы говорите про ограничения кол-ва полей, то, видимо, держите в голове какую-то конкретную СУБД. У современных СУБД ограничения такого рода - огромные. На бурную фантазию хватит. Напр., для postgres8.4: кол-во строк в таблице - скока хошь, столбцов - 250-1600 в зависимости от типа. Но даже наличие таблицы с 150 полями как бы заставляет задуматься о целесообразности... Но если и это ограничение достигнуто - его легко обойти. Как - напишу ниже, немного в др. контексте.
>>А зачем join-ы? А вдруг в тех двух таблицах внезапно появятся данные... Обычно,
>>если "вдруг" настает и нужно хранить доп. данные, делают ALTER TABLE
>>или создают новую таблицу.
>Нступает "вдруг", вы делаете ALTER TABLE и добываляете еще поле (или несколько).
>Потом еще "вдруг" ... Так может сразу выделить в отдельную таблицу?
>К тому же после каждого ALTER TABLE придется корректировать скрипты.Да, так делают. Но не сразу. Делить таблицу из 10 полей может быть нецелесообразно. Потому, что при запросах с "where name1 like '...'" тупой sequential scan может выполниться быстрее чем несколько join-ов с таблицами, в которых хранятся отдельные вынесенные св-ва сущности. А еще каждый join потребует seq scan или index scan, ведь у вас же есть условия соединения, да? Да и читабельности коду с такими запросами это не добавляет.
Если "вдруг" наступает внезапно и много раз, и таблица уже сильно разрослась вширь, делают очень просто: из всей сущности выделяют поля, которые редко или никогда не меняются и те, которые меняются часто (это для случая увеличения производительности индексов, дисковой подсистемы, кешей и проч.); либо выделяют поля, которые часто используются в типовых запросах и те, которые редко. И уже эту часть выносят в отдельную таблицу.
Типичный пример: таблица с данными о товарах электромагазина. Имеет смысл вынести все второстепенные хар-ки товара (большое описание, маркетинговая лабуда, цвет, кол-во в упаковке, инфа, которую решили добавить "вдруг", еще одно "вдруг"-поле и т.д.) в отдельную таблицу, а id, наименование и размеры оставить в первой. Ибо в работе на один запрос типа "хочу все знать о товаре" придется сотня запросов типа "положить id-такой-то в basket с quantity=100500", "сколько штук id-такого-то поместится в морской контейнер" и т.д. Конечно, к такому подходу легко прикрутить ваш принцип вынесения полей сущности в отдельные таблицы (юзаем только то, что надо; дырявых таблиц нет), но выигрыша он не даст, хотя бы по той же причине, что seq scan по таблице может быть быстрее нескольких join-ов.
О, мысль пришла: а ведь графическое представление БД по вашему принципу может способствовать инфаркту даже у закаленного спеца. Опасно! :)) Конечно, проектировка БД - это всегда компромисс. Между скоростью и понятностью, надежностью и ресурсами... Можно создать БД, которая работает быстрее любого биллинга сотового оператора при размерах больше, чем все биллинги ОПСОСов в мире. Но разобраться в ней и добавить новую фичу сможет только один человек. И требует за свою работу 100000 евро в час... Это я к тому, что, возможно, ваши методы были актуальны, когда вместо одного hdd на 100Мб можно было сделать ремонт в квартире, а проц 486DX2 был завистью всех ит-шников района. Но сейчас они имеют низкий вес в задаче достижения того пресловутого компромисса. ps: "вашими" методы я назвал не из-за того, что вы их придумали, а оттого, что их пропагандируете.
>>Если вы избавляетесь от лишних полей в основной таблице, зачем
>>поле id в дополнительной? Оно вам там ничего уникально не сыдентифицирует
>>и с ним вы ничего осмысленного не получите. Если в основной
>>таблице вашими методами вы избавились от name1, name2, name3 и таких
>>же description, то напр, запрос вида "обнови второе имя у сущности
>>с id=999" выполнить не получится.
>Избавиться от лишних полей не самоцель. В исходной таблице идут name1, name2,
>name3. Вы точно знаете что их порядок не имеет значение?А вы точно знаете, что порядок _будет_ иметь значение?
select name1, name2 from... и select name2, name1 from ... - вы об этом?>Поля id нужны для сортировки. Без них (если нужно) в точном порядке
>вывести значения будет нельзя. А как внести правку? А удалить?Я вот потому и оставил своей писанины выше, т.к., фактически, спрашивал то же самое. Впрочем, в предложенной модели EAV это сделать можно (если вы знаете точное наименование аттрибута; а если юзаете EAV, то должны знать), а в вашей модели - неизвестно.
Впрочем, я все равно не до конца понял струткуру таблицы из вашего поста с "Если количество полей name и description не соответствуют друг другу то нужно создавать две дополнительные таблицы". Приведите, плиз, пример на sql если, напр., у меня есть name1, name2, name3 и descr1, descr2. А потом и подискутируем )
>А на счет скоращения количества полей, то согласитесь, что довольно существенно поменять
>хотя бы одно поле varchar(999) на одно int.Тут не соглашусь :) Как можно вот так просто поменять текстовое поле на числовое? Если разработчик БД для хранения, напр., текущего курса валюты использует varchar(999), то я бы его перевел обратно в 5-й класс школы.
А если в общем, то как смена типа поля коррелирует с сокращением количества? :)>>вообще кошернее смотреться будет: вместо ... JOIN b on (a.id=b.parent_id) вы
>>напишете ... JOIN b using(id). А те субд, что умеют NATURAL
>>JOIN, так вообще сказка: ... NATURAL JOIN b. Согласитесь, удобнее.
>>По большому счету, это мое утверждение спорно, но лишь в том случае,
>>когда на свет вылазят защитники принципа "имя таблицы не должно дублироваться
>>в именах столбцов"
>Соглашусь что утверждение спорно :)
>Дело привычки по большому счетуНе, я согласился с собой, что мое утверждение спорно в том случае, когда на свет вылазят тролли (редкое явление). А в остальных 99% случаев - я сильно "за".
Я бы сказал, это дело ситуации (99%), а не привычки. И опыт это подтверждает. Напр. в данный момент, расширяя функционал некоего сайта, а уже просто запарился делать join-ы с условием типа ON(что_то_id=что_то), когда PK обозван что_то_id, а FK - что_то. Чисто механическая работа утомляет :) В конце концов, человек делает для человека, а не машины. Надо ценить и труд тех, кто придет на смену :) Ну и надо стараться, чтобы ваш код не прослыл индийским. Тем более, что принципы именования - есть некий неформальный стандарт, следование которому облегчает жизнь другим и способствуют укреплению репутации "профессионал" за вами.
>Я не " тотальный рационализатор", но иногда вижу как лучше. И не
>надо кидаться в крайности обзывая меня "фиговый вы "запроектировщик". Фраза "дырявые
>таблицы" придумана не мной и, очевидно, не просто так.Вы не поверите сколько людей вокруг, которые считают, что "видят лучше". %)) Но не видят перед глазами труд и опыт других. Впрочем, СУБД разрабатывают тоже далеко не дураки. И будь вы таким, мои доводы разбили бы в пух и прах за четыре предложения :) О вас мне сложно судить, могу только предполагать, что если вы - человек с несколькими вышками за плечами, то основываетесь на методах "старой" школы, а если молодой и начинающий спец, то просто все - это дело опыта.
А про "запроектировать" я съязвил скорее в том контексте, что в определенных средах есть уже давно устоявшаяся терминология в общении, а всякие девиации годятся для цитат на башорг. Ну это примерно как спросить у военного на стрельбище "а че за патрончиками вы пуляете" вместо "доложите о типе используемых выстрелОв".>А! Так это чтобы дух отвести?
>Кошке привет!Ну и Вам хорошего остатка Вечера Пятницы! ;)
НАРОД большое спасибо за ёмкий ответ.
Все выходные переваривал и по ходу ещё до конца не переварил.Ещё раз спасибо всем за пинок в нужном направлении!!! ;)
>НАРОД большое спасибо за ёмкий ответ.
>Все выходные переваривал и по ходу ещё до конца не переварил.Да не парься особо, все со временем придет, а за раз все и не переваришь - каша получится :)
применить к каждому елементу массива $str ф-цию addslashes()
>применить к каждому елементу массива $str ф-цию addslashes()Спасибо большое за функцию!!! Очень помогла