0

我有这个表,我敢打赌,在看表,你会知道我的问题已经:)鸡和蛋:数据库设计

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_textabout_main_text,等...)。我只需要创建一个通用部分,并让paging_table负责其余部分,因为各部分也会有很多显示选项(存储在另一个表中,参考content_table.id)。如果我要在两行中存储具有非常相似选项的类似部分,那看起来不好吗?

然后我创建了一个root内容(id = 0content_table)。所有主要页面和部分都将以root作为其父项。

我现在的问题是,我想要FOREIGN KEYparent_id引用rel_id列。但我有Root元素担心。我已经觉得我正在对paging_table的第一行进行破解。我现在感觉到了根内容的鸡和鸡蛋的情况。你认为真正需要根内容吗?通用部分方法如何?我只是想更好地设计这个数据库:),或者可能是CMS的架构整体重新设计,因为我刚刚开始,而且我还没有做很多。

批评非常受欢迎(只是建设性的)。如果有什么模糊的地方,请发表评论,我会尽力澄清它,我只是很难说清我脑海中的想法,如果我只是将源代码发送给我的课程,那真的很麻烦建造。谢谢!

编辑

我编辑的ID的使引用明确

+0

我不明白paging_table的功能,你能解释一下吗?你的设计与子打字(指向内容记录的部分)听起来很好。 – buddhabrot

+0

嗨!那么因为每个部分都是通用的,所以我必须找到一种“混搭”部分和页面的方法。这是否回答? –

+0

好的,我会回答。 – buddhabrot

回答

0

我真的不觉得有问题。我只是将Root的parent_id保留为Null:它没有父项,也不是他自己的父项。
否则,SQL Server(可能还有其他一些RDBMS)有hierarchical capabilities

+0

但是这会阻止我在parent_id中添加一个引用rel_id的外键,对吧? –

+0

@Rolando Cruz:我不这么认为。可以定义联接(在这种情况下为自联接),允许FK值为空 –

+0

您可以使用RDBMS为层次结构建模,但现在有更好的替代方案。 –

0

让我blasphemic:关系数据库不适合这样的任务 - 与建筑的关系明确的层次结构吮吸。我也曾犯过同样的错误,并且永远不会再这样做。我创建了一个小而轻量级的CMS,只有文件系统作为存储和XML文档。其他概念,如版本控制,复制,工作流很容易与 (惊喜!!!!) - 一些源代码版本系统,如git或svn。

另一个选择是面向文档的数据库,比如MongoDB(还有其他的,但我现在最熟悉mongo) - 没有模式,简单的扩展,扩展性好 - 你还需要什么? (且有PHP驱动程序)

要使用的标准化数据地狱)

+1

“亵渎”?我认为适当的术语是“亵渎”。其余的东西都是现货,即使它是亵渎。 – duffymo

+1

我不同意:请使用规范化的数据进行操作,这会为您节省功能区域的痛苦。 – buddhabrot

+0

嗯......我实际上是一名自学成才的开发人员,对数据库管理的经验很少(我刚刚在2周前阅读了关于正常形式的LOL)。但我会研究MongoDB。我的担心是可用性,因为大多数托管站点只提供PHP MySQL,我打算将它作为一个开源项目发布(是的,非常雄心勃勃)。我不想因为我在MySQL上使用MongoDB而吓跑最终用户。但我真的会看看MongoDB,并权衡后果 –

0

你的分割点的内容记录了,这是件好事。 但是,您需要摆脱尴尬paging_table:

每个部分可能指向一个页面并具有一个整数,描述该父项关系中的“顺序”。 如果一个部分没有指向一个页面,它指向另一个部分,你可以重复使用“order”字段。

所以你有parent_page和parent_section字段,其中一个可能是NULL。如果你疯狂的正常化,你需要更多的分节表,但你可能需要比你想象的更多。

请注意,您将丢失content_table中的层次信息,但这没有问题,因为通常没有关于所有“内容”的层次结构。只有部分是分层的。

一个更简单的方法是将页面看作只是一个没有父节的节类型。但是我对其他可能涉及页面的数据知之甚少。然而,在一个普通的Wiki中,我会使用它。

编辑: 如果你真的需要“再利用”的实际科的记录,你需要一个SectionAssignment表,允许分区和页面之间的M-N的关系。 SectionAssignment将有四个字段:assignment_id,section_id,page_id和order。

+0

嗨。如果我将某个部分指向一个页面,那么我将不得不为另一个页面的类似部分创建另一行?所以我有两个部分的重复数据,其唯一区别是他们属于不同的页面(即在一列中的差异) –

+0

我编辑了问题以使事情更清晰 –

+0

如果它们属于不同的页面,他们究竟有什么共同点?标题?未来任何人都可能改变,对吧?似乎你只是想要两个记录。 – buddhabrot