我有一个问题。
假设我有2张桌子
Parent(nameParent, children)
显然,如果我有:
Parent
'Mary' | 'John'
'Mary' | 'Dan'
'Mary' | 'Chris'
我有nameParent
个重复的条目。所以如果我有:
Parent(nameParent)
'Mary'
Child(nameChild, nameParent)
'John' | 'Mary'
'Dan' | 'Mary'
'Chris'| 'Mary'
这是否比第一个例子更有效,因为nameParent
是指向父Mary的指针,而不是磁盘上占用空间的条目?
答案 0 :(得分:2)
高效?有些。您应该更多地关注设计和性能而不是物理磁盘空间。它确实提供了参照完整性。这个问题的典型设计将是:
id | name | parent_id 1 Mary NULL 2 John 1 3 Dan 1 4 Chris 1
答案 1 :(得分:1)
磁盘空间方面,VARCHAR
只需(大致)提供您提供的最大字节数(VARCHAR(16)
总是需要VARCHAR(8)
的两倍),{{1}通过总结所有字段,很容易估计每行的磁盘空间量(减去索引):
INT
理想情况下,永远不要将相同的字符串存储两次以避免重复数据。在您的情况下,最好用指向父表的数字ID替换INT id -- 4 bytes
CHAR name(15) -- 15 bytes
TEXT description -- variable, depending on the content
列。
也就是说,索引也会占用磁盘空间,大约是字段大小的两倍乘以行数。我们假设您将nameParent
密钥(id
)设为主键,其中2048行占用大约16千字节。
在估算每行表的总磁盘使用量时,将所有字段的大小相加,然后只需添加索引的大小。这将给你一个粗略的估计。
实际重要的部分
当然,磁盘空间对数据库来说并不重要,您应该始终关注性能。除非你的表格变得非常大(数百万行),否则根本不会成为一个问题。
在特定情况下,只需制作一个包含字段int
,person
和id
的{{1}}表格。对于那些没有父级的人,将parent
字段设置为name
,让孩子们使用parent
字段来指定他们的父级。然后你就可以在一张桌子上找到所有东西,你可以代表整个家庭系列,而且它仍然很容易。
答案 2 :(得分:0)
考虑创建名称表以消除数据冗余,同时提高数据完整性。
create table Names (
ID MEDIUMINT NOT NULL AUTO_INCREMENT,
Name VARCHAR(30) NOT NULL,
PRIMARY KEY (ID),
UNIQUE (Name)
);
create table ChildParentNames (
ChildName MEDIUMINT,
ParentName MEDIUMINT,
FOREIGN KEY (ChildName) REFERENCES Names(ID),
FOREIGN KEY (ParentName) REFERENCES Names(ID)
)