0

基本上情况是这样的(简化,伪代码):

我有 2 TABLES 人和国家。

人员表:

KEY INT ID, STRING NAME, STRING COUNTRY

国家表:

KEY INT ID, STRING COUNTRY_NAME

客户可以控制国家表中的内容,因此他可以在列表中添加和删除县。创建人员时,此国家/地区值显示在下拉列表中。创建人员时,国家字符串值将插入到人员行的国家列中。

对我来说,这个 Person 应该有一个对国家的外键引用是有道理的,但是因为客户可以控制 Country 表中出现的内容,所以它们被保存为单独的表,因为你不能只删除使用过的国家,(参照完整性和所有)。这是我的一位同事提出的在这种情况下不使用外键的论点,但我觉得应该有更好的解决方案来解决这个问题,那么,我的同事是对的还是有更好的解决方案?

客户端可以在国家/地区表中添加和删除值,但如果从国家/地区表中删除一个值,使用该值的创建人应保留其值。

4

3 回答 3

1

您可以指定FOREIGN KEY删除引用表的记录时要做什么的选项:(这些是MySQLON DELETE ([RESTRICT | CASCADE | SET NULL | NO ACTION])中可用的选项)。

一般来说,您应该使用外键。例如,如果人们提到一个国家,为什么可以删除它?如果没有外键,您需要手动检查引用。

在您的示例中,我还将使用国家/地区的 ID 字段作为参考。您可以更改国家/地区的名称,所有引用该 ID 的人都将获得此信息(当然,您需要加入)。

此更新的另一个解决方案是为ON UPDATE CASCADE原始外键指定一个选项,从而在Country更改国家名称时更新相应人员的所有字段。

于 2011-11-14T14:22:29.567 回答
1

创建一个 isactive 列,历史记录的数据将显示最初选择的县(或更新值,见下文),并且可以调整下拉列表以仅显示活动国家。在任何情况下都不应删除外键约束。这是数据完整性问题的秘诀。

将想法设置为空通常也是一个糟糕的设置。您不想丢失有关此人所在国家/地区的数据。

如果国家/地区可能发生变化(而不是添加新国家/地区),那么您可以使用级联更新,但在这种情况下最好使用代理键(不应更改)。然后,如果名称被更改,它会在各处反映出来,而无需更新数百万个子记录。

于 2011-11-14T14:26:22.370 回答
0

数据库已被设计为处理仍由外键引用的记录的删除。

您仍然应该使用外键,并指定您希望它如何与on delete. 如果您想允许删除仍然(由人)引用的记录(国家),请使用

foreign key country_id references countries(id)
    on delete set null;

如果您希望外键防止引用的国家/地区消失,请省略该on delete子句,尝试删除仍被引用的国家/地区将失败。这通常是期望的行为;尝试将数据库置于无效状态应该会失败。

无论关联记录的外键设置为null,还是阻止被引用记录的删除,外键仍然强制并维护引用完整性。这是他们的工作,而且他们很擅长。

于 2011-11-14T14:12:53.020 回答