0

我有个问题。

假设我有 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 的指针,而不是占用磁盘空间的条目?

4

3 回答 3

2

高效的?有些。您应该更多地关注设计和性能,而不是物理磁盘空间。它确实提供了参照完整性。这个问题的典型设计是这样的:

编号 | 姓名 | parent_id
1 玛丽 NULL
2 约翰 1
3 丹 1
4 克里斯 1
于 2013-01-27T21:03:43.307 回答
1

磁盘空间方面,aVARCHAR只占用(大致)您提供的最大字节数(VARCHAR(16)总是占用 2 倍VARCHAR(8)),anINT是恒定的 4 个字节,等等。很容易估计每行的磁盘空间量(减去索引) 通过总结所有领域:

INT id           -- 4 bytes
CHAR name(15)    -- 15 bytes
TEXT description -- variable, depending on the content

理想情况下,通过从不存储相同的字符串两次来避免重复数据。在您的情况下,最好将nameParent列替换为指向父表的数字 ID。

也就是说,索引也会占用磁盘空间,大约是字段大小乘以行数的两倍。假设您将id键 ( int) 设为主键,如果有 2048 行,它将占用大约 16 KB。

在估计每行表的总磁盘使用量时,将所有字段的大小相加,然后只需添加索引的大小。这会给你一个粗略的估计。


真正重要的部分

当然,磁盘空间对于数据库来说并不重要,您应该始终关注性能。除非您的表会变得非常大(数百万行),否则这根本不会成为问题。

在您的特定情况下,只需person使用字段id和制作一个表格。为那些没有父母的人设置字段,并让孩子使用该字段来指定他们的父母是谁。然后你把所有东西都放在一张桌子上,你可以代表整个家族,这仍然很容易。parentnameparentNULLparent

于 2013-01-27T21:16:06.793 回答
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)
)   
于 2013-01-27T21:16:21.803 回答