Цыпленок и яйцо: дизайн базы данных - PullRequest
0 голосов
/ 08 декабря 2011

У меня есть этот стол, держу пари, что, глядя на столы, вы уже знаете мою проблему:)

content_table
--------------------------------------
| id |   title   | type  | parent_id |
--------------------------------------
| 0  |   Root    | Page  |    0      |
|100 |   Home    | Page  |    1      |
|101 | Main Text |Section|    1      |
|102 |   About   | Page  |    1      |
|301 |    Foo    | Text  |   245     |
|302 | About Us  | Text  |   246     |
--------------------------------------

paging_table
---------------------------------
| page_id | section_id | rel_id |
---------------------------------
|   0     |     0      |    1   |
|  100    |    101     |   245  |
|  102    |    101     |   246  |
---------------------------------

section_options
----------------------------
| section_id | option_mask |
----------------------------
|   101      |   65535     |
----------------------------
*paging_table.page_id and paging_table.section_id 
  both have FOREIGN KEYs on content_table.id

 section_options.section_id has a FOREIGN KEY on content_table.id

Так что в основном у меня есть CMS, и я хочу рассматривать ВСЕ как контент, будь то страница, раздел страницы или фактическое содержимое самих страниц.

Во-вторых, поскольку некоторые разделы страницы будут очень похожими, я решил, что мне не нужно создавать несколько разделов (например, home_main_text , about_main_text и т. Д.). Мне просто нужно создать общий раздел и сделать так, чтобы paging_table позаботился обо всем остальном, поскольку у разделов также будет множество параметров отображения (они хранятся в другой таблице со ссылкой на content_table.id). Если бы у меня были похожие разделы с очень похожими параметрами в двух строках, это бы выглядело плохо, не так ли?

Затем я создал контент rootid = 0 на content_table). Все главные страницы и разделы будут иметь root в качестве родителя.

Моя проблема сейчас в том, что я хочу поставить FOREIGN KEY на parent_id, который ссылается на столбец rel_id. Но мне нужно беспокоиться о Root элементе. Я уже чувствую, что делаю хак в первом ряду paging_table. Я сейчас чувствую сценарий курицы и яйца для содержимого корня. Как вы думаете, действительно ли необходимо корневое содержимое? Как насчет общего подхода к разделу? Я просто хочу улучшить дизайн этой базы данных :) или, может быть, полностью изменить архитектуру CMS, так как я только начинаю и на самом деле я еще мало что сделал.

Критика очень приветствуется (просто будьте конструктивны). Если есть что-то расплывчатое, пожалуйста, прокомментируйте, и я попытаюсь прояснить это, мне просто трудно сформулировать, что я имею в виду, и было бы действительно хлопотно, если бы я просто отправил вам исходный код классов, которыми я являюсь строительство. Спасибо!

EDIT

Я отредактировал идентификаторы, чтобы сделать ссылки понятными

Ответы [ 3 ]

0 голосов
/ 08 декабря 2011

Ваш раздел сейчас указывает на запись контента, это хорошо. Однако вам нужно избавиться от неловкого paging_table:

Каждый раздел может указывать на страницу и имеет целое число, описывающее «порядок» в этих родительских отношениях. Если Раздел не указывает на Страницу, он указывает на другой Раздел, вы можете повторно использовать поле «Порядок».

Итак, у вас есть поля parent_page и parent_section, одно из которых может быть NULL. Если вы без ума от нормализации, вам понадобится больше таблиц секций, но вам может понадобиться больше, чем вы думаете.

Обратите внимание, что вы потеряете иерархическую информацию в вашем content_table, но это нормально, так как нет ничего общего с иерархией всего "контента". Только разделы являются иерархическими.

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

EDIT : Если вам действительно нужно «повторно» использовать фактические записи Раздела, вам нужна таблица SectionAssignment, которая допускает отношение m-n между Разделами и страницами. SectionAssignment будет иметь четыре поля: assignment_id, section_id, page_id и order.

0 голосов
/ 08 декабря 2011

Я не вижу там проблемы. Я бы просто оставил parent_id для Root на Null: у него нет родителя, и это НЕ его собственный родитель.
В противном случае SQL Server (и, возможно, некоторые другие СУБД) имеют возможности иерархии .

0 голосов
/ 08 декабря 2011

Позвольте мне быть богохульным: реляционные базы данных не подходят для такого рода задач - построение иерархий с отношениями явно отстой.Я тоже однажды совершил ту же ошибку, и никогда больше этого не сделаю.Я создал небольшую и легкую CMS с файловой системой в качестве хранилища и документами XML.Другие понятия, такие как управление версиями, репликация, рабочий процесс, легко надеть (удивительно !!!!) - некоторые системы управления версиями, такие как git или svn.

Другим вариантом может быть документно-ориентированная база данных, такая как MongoDB (есть и другие, но сейчас я больше всего знаком с монго) - нет схемы, просты в использовании, хорошо масштабируется - что еще нужно?(и есть драйвер PHP)

К черту нормализованные данные;)

...