我目前有这个数据库结构:
一个条目可以包含“file”,“text”和“url”类型的多个项目。
这些项目中的每一项都在文本,网址或文件表中只有一个相应的项目 - 存储数据。
我需要一个查询来有效地选择包含所有相应项目及其数据的条目。
所以我的第一种方法就像
SELECT * FROM entries LEFT JOIN entries_items LEFT JOIN texts LEFT JOIN urls LEFT JOIN files
然后遍历它并在我的应用程序中进行后期处理。
但事实是,不太可能存在多种不同类型的物品。它甚至是罕见的情况,每个条目存在多于一个项目。在大多数情况下,它将是一个文件。但我还是需要它......
所以不要扫描eveyr项目的所有3个表格我认为我可以做一些像case / switch这样的事情,并根据entries_items中“type”的值扫描相应的表。
但我无法让它发挥作用。
我还考虑过在应用程序中创建case / switch逻辑,但是我会有多个查询,因为mysql服务器将是外部的,所以可能会慢一些。
如果你有更好的方法,我也可以改变结构!
我还将“texts”,“urls”和“files”的所有字段放在表entries_items的旁边,因为它只有1:1的关系,并且只有不需要的所有内容为null。 这有什么优点/缺点?我认为它需要更多的存储空间,我不能像我现在拥有它们那样做我的cosntraints。一切都需要为空......
我对各种想法持开放态度。该应用程序尚未编写,所以我基本上可以改变我喜欢的任何内容。
答案 0 :(得分:1)
我首先考虑在“entries_items”表中添加一个列,其中包含文本,网址和文件的XML表示形式。我不能代表MySQL,但SQL Server有很好的处理XML的工具。我敢打赌MySQL也是。
如果不是像这样的最先进的技术,那么我会考虑复古并且只有一个具有许多空值的项目表,正如您已经考虑过的那样。
答案 1 :(得分:1)
您有三种不同的实体类型(URL,TEXT,FILE)通过中间表ENTRIES_ITEMS链接到主要的ENTRIES表,并且您使用这种“条件连接”方法违反了普通表单。给定您的结构,不可能在ENTRIES_ITEMS.id上声明外键约束,因为id列可以引用URLS,TEXTS或FILES表。要规范化ENTRIES_ITEMS表,您必须添加三个单独的字段,urlid,textid和fileid并允许它们为空,然后您可以通过链接表将三个实体表中的每一个连接到ENTRIES表。您正在采用的方法非常常见于不符合SQL92的遗留数据库,其中的值是以编程方式/过程方式从实体表中获取的,而不是使用SQL选择以声明方式获取。
答案 2 :(得分:1)
这可能会让您入门,但不会解析entries
和entries_items
的层次结构(parent_id)。
select *
from entries as e
join entries_items as i on i.entry_id = e.id
left join texts as t on t.item_id = i.id and i.type = 'text'
left join urls as u on u.item_id = i.id and i.type = 'url'
left join files as f on f.file_id = i.id and i.type = 'file'
;
如果考虑模型清理,这可能是一个起点。