我有这张桌子,我打赌看着桌子,你会知道我的问题:)
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
的表中) 。如果我要将类似的部分与非常相似的选项存储在两行中,那看起来会不好吗?
然后我创建了root
内容(id = 0
处content_table
的内容。所有主要页面和部分都将root
作为其父级。
我现在的问题是,我想在引用FOREIGN KEY
列的parent_id
上加rel_id
。但是我要担心Root
元素。我已经觉得我在paging_table
的第一行做了一个黑客攻击。我现在感觉鸡肉和鸡蛋的情况根本内容。您是否认为根内容确实存在必要性?通用部分方法怎么样?我只是想要更好地设计这个数据库:),或者可能是CMS的体系结构的整体重新设计,因为我刚开始并且我还没有做太多。
非常欢迎批评(只是建设性的)。如果有任何含糊不清的内容,请发表评论,我会尽力将其清理干净,我只是很难清楚地表达我的想法,如果我只是向您发送源代码,那么这将是一件很麻烦的事情。建造。谢谢!
修改
我已经编辑了id以使参考清晰
答案 0 :(得分:0)
让我亵渎神明:关系数据库不适合这种任务 - 建立层次关系显然很糟糕。我也犯过一次同样的错误,再也不会这样做了。我用文件系统作为存储和XML文档创建了小而轻的CMS。版本控制,复制,工作流等其他概念很容易上传 with(surprise !!!!) - 一些源版本控制系统,如git或svn。
另一种选择是面向文档的数据库,如MongoDB(还有其他的,但我现在最熟悉mongo) - 没有架构,简单的hiarachies,扩展得很好 - 你还需要什么? (并且有PHP驱动程序)
使用标准化数据来处理地狱;)
答案 1 :(得分:0)
您的部分现在指向内容记录,这很好。 但是,你需要摆脱尴尬的paging_table:
每个部分可以指向一个页面,并且有一个描述该父关系中“顺序”的整数。 如果Section不指向Page,它指向另一个Section,则可以重用“order”字段。
所以你有parent_page和parent_section字段,其中一个可能是NULL。如果你对规范化很疯狂,你需要更多的章节表,但你可能需要比你想象的更多。
请注意,您将丢失content_table中的层次结构信息,但这没关系,因为所有“内容”通常都没有层次结构。只有部分是层次结构的。
更简单的方法是将Page视为一种没有父节的Section。但我不太了解页面中可能涉及的其他数据。然而,在普通的Wiki中我会使用它。
修改强>: 如果您确实需要“重用”实际的Section记录,则需要一个SectionAssignment表,它允许Sections和Pages之间的m-n关系。 SectionAssignment将有四个字段:assignment_id,section_id,page_id和order。
答案 2 :(得分:0)
我真的没有看到问题。我只是将Root的parent_id留给Null
:它没有父级,而且不是他自己的父级。
否则,SQL Server(可能还有其他一些RDBMS)有hierarchical capabilities。