2009-10-29 4 views
1

Текущая ситуация в том, что темы сортируются по трем основным категориям. Существует потенциал добавить больше, чем только 3 категории, но более высокие взлеты хотят реализовать возможность добавлять более чем одну категорию к теме.Должен ли я сделать другую таблицу или просто использовать массивы? (Нормализовать или не нормализовать)

В моем первоначальном дизайне db есть идентификатор категорииID в качестве внешнего ключа в информационной таблице темы. Скорее всего, это была плохая идея с самого начала, но я полагал, что они были настроены только на 3 категории, и сделать это таким образом позволит меньше запросов.

Итак, из того, что я вижу, у меня есть два варианта: 1) Введите categoryID как строку, разделенную запятой, которую я разбираю на конце php. 2) Реструктурируйте БД и вытащите идентификатор категории в свою собственную таблицу categoryID и topicID.

Мне было интересно, что об этом думали все. Мой первый инстинкт заключался в реструктуризации базы данных. Но первый вариант, когда я думаю об этом, проще всего реализовать и наименее вероятно сломать что-то существующее, изменив db вокруг. Это также может привести к де-нормализации и открыть возможность несогласованности данных.

Я прочитал, что де-нормализация прекрасна, если вы согласны с тем, что у вас есть несогласованные данные в обмен на производительность. По вашему мнению, я получу много результатов в этом риске? Любой вклад в то, что я должен делать в этой ситуации, будет оценен по достоинству.

Спасибо за помощь,
Леви

ответ

3

Не путайте денормализацию (хороший пример которого сохраняя число голосов на SO вопроса вместе с вопросом, в отличие от расчета его каждый раз из таблицы «ГОЛОСОВ») с мерзостью, которая представляет собой список идентификаторов, разделенных запятыми.

Модель правильного отношения «многие ко многим»; есть только так много вещей, которые могут (и будут) идти не так, как с разделенным запятой. Чтобы назвать несколько:

  1. Отсутствие ссылочной целостности.
  2. Рядом с невозможным использовать в соединениях.
  3. Невозможно адекватно индексировать; немасштабирующиеся.
+0

Все хорошие моменты, третий из которых касается того, чтобы быть немасштабируемым, - это то, как я впервые столкнулся с этой проблемой с моим дизайном БД. – Levi

+0

+1 Также сложнее выполнять различные агрегированные запросы, такие как подсчет, суммирование или усреднение значений в списке. –

0

Ваш лучший вариант - иметь базу данных, как вы сказали, категорий category-topicID, чтобы найти категории, к которым относятся темы.

Вы можете сделать это другим способом, взломав строки в категорииID, но при поиске любых тем, находящихся в определенной категории, вам придется проходить через каждое поле и запускать LIKE на нем ... Гораздо более ресурсоемкий.

Потратьте время на реструктуризацию БД, и в итоге вы получите гораздо лучший результат.

0

Если вам нужно что-то сделать в СУБД с отдельными элементами, то не сохраните их в виде списка. Это заставит ваши запросы работать как собака, так как ваши таблицы становятся больше. Конечно, если вы только когда-нибудь будете рассматривать список как единое целое, нормально их хранить.

Но вы должны быть уверены, что всегда будете относиться к списку как к единице, а не к обману, заявив, что они подразделение, а затем выплескивают их где-то в другом месте - лучше позволить СУБД сделать это для вы.

Вы должны всегда делать 3NF сначала, если и только если у вас есть проблемы с производительностью, денормализовать скорость.

Эти поля, о которых вы говорите в вопросе, не являются тем видом, который вы будете рассматривать как единое целое. Вам нужно будет делать что-то для отдельных элементов в списках, поэтому их нужно разбить на другую таблицу.

+0

Хорошо, я собираюсь разбить его на другой стол, кажется, что у меня будет меньше ошибок по дороге. Любопытно, что список рассматривается как единица только тогда, когда он будет отображаться как есть? Поэтому, если у меня есть «яблоки, апельсины, бананы, киви», и я использую его для вывода «Мне нравятся яблоки, апельсины, бананы, киви». Это нормально? Выведение это, «Мне нравится: -apples -kiwis -bananas -oranges » будет плохой идеей, хотя, потому что я должен был бы взять строку и разделить его на части, чтобы отобразить его в таком порядке? Есть ли пример реального мира, который вы можете использовать в качестве единицы? – Levi

+0

Да, это нормально. Если вы просто собираетесь вытащить его как есть, а не манипулировать им, вы можете сохранить его таким образом. Это потому, что нет никакой дополнительной работы для СУБД или вашей программы для ее обработки. В этом случае на самом деле * лучше * сделать так, потому что это быстрее, чем рекомбинация отдельных столбцов в строку :-) – paxdiablo

+0

Пример реального мира? Как насчет сайта знакомств, на котором вы перечисляете свои интересы (что может быть * что угодно, поэтому может не иметь смысла в качестве таблицы поиска). Вы вполне можете войти в «прогулки по пляжу, разработка Java и инструменты для пыток с 16-го века», и это будет представлено как потенциальным кандидатам (которые тогда, честно говоря, могли бы бежать, как ад). – paxdiablo

Смежные вопросы