MySQL. Сколько же таблиц оптимально?
Собственно понятно, что для одних задач более оптимальные это многотабличные БД, для других более оптимально юзать малотабличные. Вот и интерисует мнение тех, кто с БД много работал, т.е. практическая сторона. В каких случаях лучше делать кучу таблиц, в каких лучше мало?
Просто вот думаю... есть БД каталог в которой есть список товаров, список покупателей и покупки (таблица которая связывает таблицу товаров и покупателей). Я вот думаю, лучше сделать все покупки в одной таблице, или, например, для каждый суток создавать отдельную новую таблицу? Ибо потом еще нужно в админке генерировать отчеты по дня и если у нас каждый новые сутки будет новая таблица, то выбрать нужные сутки будет просто, если таблица одна, то придется сканить всю таблицу (ну или её часть учитывая что первичный ключ это время в *них формате).
Нет, не будет. В базах данных как правило нет нужды читать всю таблицу, чтобы выбрать несколько строк. Сложность при этом заключается лишь в правильной расстановке индексов. Например, если у тебя в таблице есть поля "сообщение","id пользователя","id ветки" (разумеется, их на практике должно быть куда больше, но ограничимся пока этим), то если тебе часто приходится читать из таблицы запросом типа select ... where 'id_ветки'=... , то при наличии индекса на поле id_ветки запрос будет произведён очень быстро при многогигабайтной таблице.
Применительно к MySQL читай
http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
Одну таблицу и правильную расстановку индексов. Если размер таблицы перевалил за несколько гигабайт, то можно архивировать старые данные в другую таблицу.
За первичный ключ в timestamp надо расстреливать на месте. В MySQL есть auto_increment, в Oracle-последовательности и триггеры (а, вероятно, и более простой способ) - в любом случае в каждой нормальной БД вопрос генерации первичных ключей решён.
Применительно к данному случаю рекомендую:
Заменить timestamp на time и date. А если MySQL умеет строить частичные индексы по datetime (в чём я сомневаюсь), то на него.
Внимательно прочитать http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html и расставить соответствующие индексы. В целом, согласно содержимому этой ссылки, индексы на сбалансированных бинарных деревьях будут использоваться и при выражениях timestamp<... and timestamp>=..., но всё же рекомендую сделать по-человечески.
Да, и не забудь сделать внешние ключи для контроля целостности данных - по-моему, индексы на внешние ключи MySQL использует автоматически.
Вообще возможности баз данных сильно отключаются от XML - применительно к веб-ресурсам здесь важна устойчивость к многопоточному доступу (когда много клиентов одновременно читают/пишут данные из одной таблицы), чему помогают блокировки, транзакции и методы их разрешения.
Однако в силу вопроса, выдающего твою низкую квалификацию в этой области, очень рекомендую почитать литературу по базам данных, так как неправильное проектирование таблиц может повлечь очень плачевные последствия в плане объёма переписываемого кода. Также как альтернативу можешь освоить библиотеки ORM (объектно-реляционного отображения), которые вбирают себя работу со многими типичными случаями без необходимости писать запросы вручную. К сожалению, я не знаю очень хорошей библиотеки для PHP, но если тебе вэтом вопросе так ничего и не посоветуют, можешь попробовать phpdoctrine, однако сразу предупреждаю, что по тупости её разработчика в персистентных классах там нельзя использовать свои конструкторы.
Автор подразумевал, похоже, полнотекстовый поиск подстроки в тексте сообщений форума. Тут индексация особо не поможет. Например, если пользователь хочет получить список сообщений (или тем) форума, где встречается подстрока "Вася Пупкин", то придётся тупо идти по всем сообщениям.
[INDENT] Цитата: Сообщение от alekciy
Просто вот думаю... есть БД каталог в которой есть список товаров, список покупателей и покупки (таблица которая связывает таблицу товаров и покупателей). Я вот думаю, лучше сделать все покупки в одной таблице, или, например, для каждый суток создавать отдельную новую таблицу?
[/INDENT]Зачем усложнять? У тебя разве предполагается добавление порядка миллиона записей о покупках за один день? Сомневаюсь, что хотя бы порядка тысячи наберётся. Прикинь насколько быстро будет забиваться таблица покупок и сделай периодическое перемещение части информации из основной таблицы в архивную. А лучше вообще в архивную БД.
Просвети, пожалуйста, в чём причина. Дело в том, что опыт в разработке структуры БД у меня небольшой и хотелось бы, так сказать, пользуясь моментом, повысить квалификацию.
За первичный ключ в timestamp надо расстреливать на месте.
Ну это я и не делал. Использую суррогатный ключ id. Просто подумалось, что тут у нас естественное упорядочинное поле. И потом на тип timestamp отводится 4 байта как и на int, так почему бы не юзат этот естественный ключ?
Применительно к данному случаю рекомендую:
Заменить timestamp на time и date.
Была такая мысль. Но возникает сомнение ибо тут работаем с двумя полями, а при timestamp с одним.
Однако в силу вопроса, выдающего твою низкую квалификацию в этой области, очень рекомендую почитать литературу по базам данных, так как неправильное проектирование таблиц может повлечь очень плачевные последствия в плане объёма переписываемого кода.
Книга есть, и довольно большая. Прочесть за день два ну ни как не получится :D . Но пролистав её по быстрому и порывший в предметном указателе я так и не нашел однозначно ответа в какое количество таблиц может быть оптимальным. Это я так понимаю можно вынести из практики проектирования не одной БД. Поэтому и запостил.
Также как альтернативу можешь освоить библиотеки ORM (объектно-реляционного отображения), которые вбирают себя работу со многими типичными случаями без необходимости писать запросы вручную.
Э нет, это в данный момент не наш метод :) . Сейчас как раз и нужно писать вручную и писать много. Имхо, как с HTML. Народ лучше понимаем что это и зачем когда работает с исходной разметкой без всяких там визуалок. И тут блокнот рулит :D
Если сервер позволяет полноценно формировать timestamp из даты и времени в запросах, почему бы и нет? Первичный ключ может быть не только суррогатным, но и натуральным - перечитай теорию. В некоторых задачах натуральные ключи рулят.
С остальным согласен.
И не мудрено, ибо вопроса "оптимального количества таблиц" в теории реляционных БД не существует. Сколько требуется по модели (зависящей от решаемой задачи), столько и делают. У сервера может быть ограничение на число таблиц в одной БД, как правило, очень большое, вроде 4096 или 65536.
А ляпать по таблице на каждую ветку форума - однозначный маразм.
шутка конечно. нельзя так вопрос ставить. тут вопрос в правильном проектировании БД.
на данном этапе лучше освоить нормлаьные формы (а это вообще должен назубок знать любой дизайнер БД)
http://ru.wikipedia.org/wiki/Нормальная_форма
хотя некоторые даже и не догадываются, но большинство разработчиков работают с 3NF.
Ежели ты сознательный программист, то всё поймёшь и будет ясно, что делать дальше.
в любом случае плодить таблицы нельзя. БД теряет всякий смысел.
на данном этапе лучше освоить нормлаьные формы (а это вообще должен назубок знать любой дизайнер БД)
http://ru.wikipedia.org/wiki/Нормальная_форма
Я знаю правила нормализации данных, более того, делал их, пусть и для простых БД. Вопрос то не по нормализации, а по скорости.
в любом случае плодить таблицы нельзя. БД теряет всякий смысел.
Почему? Объективная причина есть? Например в данном форуме 22 ветки, я думаю, что 22 таблицы в БД сделать не трудно. А работать было бы удобнее с 22 таблицами, чем с одной. Разве нет?
Это как раз не проблема. В PHP как раз для это все есть. На мускул будут идти уже отформатированные timestamp.
И не мудрено, ибо вопроса "оптимального количества таблиц" в теории реляционных БД не существует.
Вот и я чухнулся и тишина... это ведь только из практики и вытекает, сколько для каких задач оптимально или какое количество выбрать при определенной поставноке задачи. Поэтому на форум и полез.
Да. Первое правило разумного решения задач - не умножать сущностей без надобности.
См. выше. Если задача решаема одной таблицей, в 21-й оставшейся нет надобности. У тебя неправильное понятие о БД или серьёзный разрыв теории с практикой.
См. выше. Если задача решаема одной таблицей, в 21-й оставшейся нет надобности. У тебя неправильное понятие о БД или серьёзный разрыв теории с практикой.
Хм.. а если 22 таблицы будет быстрее, чем одна?
если себе - то одну, а компьютеру, точнее СУБД всё равно.
вопрос в том, как ты с помощью скриптов будешь переключаться между таблицами.
разницы ИМХО не будет. но зачем МНОГО когда проще ОДНУ? БД десятки лет проектируются, и поверь разработчики обо всём давно подумали.
а прикинь, если тебе нужно сделать запрос по всему архиву, то есть по всем 22 таблицам? что, 22 запроса? или UNION, что в принципе однох... а если тебе структуру сущности надо поменять?
Лично я не видел, что бы в каком то проекте было много таблиц для одной сущности. Плодить таблицы имеет см%u
каждая запись - большая газетная статья + куча параметров.
в день наполнение 50-100 записей.
база живёт почти три года скоро будет (хм, когда я её проектировал мне было 18 и это была моя первая БД )))
сейчас там записей около 100000 и ничего, всё работает. кстати полнотекстовый поиск без индекса тоже нормально, 0.1 в среднем выдача ответа от базы (применял FULLTEXT).
и пока ни разу даже мыслей таких не было, чтобы пилить на отдельные таблицы, ибо перед этим много читал и общался с разработчи%u
Если же записей будет более 1 миллиона и нагрузка будет относительно высокой (более 10 запросов в секунду) - тогда нужны другие подходы и MySQL тут уже отдыхает.
0.1 - текстовые поисковые запросы по FULLTEXT, обычные запросы и намного меньше времени занимают.
В случае БД для форума одна таблица не всегда лучше нескольких (по разделам форума). Если на твоём форуме за день оставляют по несколько тысяч сообщений, то база пухнет быстро. А производить поиск по всей базе (все разделы форума) требуется достаточно редко и можно позволить себе и неудобства, и небольшую задержку.
Если же записей будет более 1 миллиона и нагрузка будет относительно высокой (более 10 запросов в секунду) - тогда нужны другие подходы и MySQL тут уже отдыхает.
В общем понятно, вполне можно в одну пихать, на производительность сильно не скажется.