Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何创建可移动外键?_Sql_Database_Database Design_Relational Database_Relational Algebra - Fatal编程技术网

Sql 如何创建可移动外键?

Sql 如何创建可移动外键?,sql,database,database-design,relational-database,relational-algebra,Sql,Database,Database Design,Relational Database,Relational Algebra,基本情况如下(简化的伪代码): 我有两张桌子,一个人一个国家 人员表: KEY INT ID, STRING NAME, STRING COUNTRY 国家表: KEY INT ID, STRING COUNTRY_NAME 客户机可以控制Country表中的内容,因此他可以在列表中添加和删除县。创建人员时,此国家/地区值将显示在下拉列表中。创建人员时,将在人员行的“国家”列中插入“国家字符串”值 对我来说,这个人应该有一个指向国家的外键引用,这是有道理的,但是因为客户机可以控制国家表中显示

基本情况如下(简化的伪代码):

我有两张桌子,一个人一个国家

人员表:

KEY INT ID, STRING NAME, STRING COUNTRY
国家表:

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

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


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

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

您仍应使用外键,并指定希望它在删除时如何使用
。如果要允许删除(人员)仍引用的记录(国家),请使用

foreign key country_id references countries(id)
    on delete set null;
如果希望外键防止被引用的国家/地区消失,请关闭删除时的
子句,尝试删除仍被引用的国家/地区将失败。这是典型的期望行为;将数据库置于无效状态的尝试应失败


无论关联记录的外键设置为
null
,还是阻止删除被引用记录,外键都会强制执行并保持引用完整性。这是他们的工作,他们非常擅长。

您可以指定作为
外键的一个选项,在删除引用表的记录时执行什么操作:
删除([RESTRICT | CASCADE | SET NULL | NO ACTION])
(这些选项在中可用)

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

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


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

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

将idea设置为null通常也是一个坏主意。您不希望丢失此人所在国家的数据


如果国家/地区可能会更改(而不是添加新的国家/地区),则可以使用级联更新,但在这种情况下,最好使用代理键(不应更改)。然后,如果名称被更改,它将反映在所有地方,而无需更新数百万子记录

也许不需要实际删除行,您可以为“isActive”或其他内容设置一列,当客户端删除国家时,将“isActive”设置为0。这样,您仍然可以保持引用完整性,但客户机仍然可以控制显示哪些国家。“客户机可以在国家表中添加和删除值”--您是本末倒置:),这是一个实现考虑事项。正在建模的业务规则是什么?我认为业务规则应该是这样的:“客户可以控制用户可以将哪些值放入国家/地区列”因此,客户无法控制更改已经放入的值。暂时忘记数据库:用户理解规则的含义是什么“列”是DBMS所理解的意思,假设企业不是从事为民族国家或类似国家撰写常规地缘政治报纸专题或制造支柱的业务;)“在这种情况下,最好使用代理密钥”--不,因为这不会防止重复,例如,我自己国家的名称,大不列颠及北爱尔兰联合王国,可能会被复制为“UK”、“Britain”、“England”等。最好使用代码或类似的标识符,并具有可信的来源。是的,但我正在搜索更多的“一般”解决方案,而不是适用于“国家”的解决方案“特别是列。@有一天,如果它们要更改,很多记录都需要更改,则不需要更改。我也使用国家代码,但在这种情况下,用户实际上在使用国家代码,因此ISO国家代码在这里似乎不合适。如果你有很多记录,我仍然会使用代理密钥。这样,当美国将其名称更改为其他名称时,你不必更改数百万条记录中的每一个地址。“当美国更改其名称时”——要么你的舌头紧紧地贴在脸颊上,要么是经典;)显然,无论是用户还是客户都无法在现实世界中重命名民族国家!国家更改名称(可能不是每天更改,但通常是一年更改几个名称)-我以美国为例,说明如果将国家名称存储在loopkup表以外的任何位置,它将如何影响您的数据库,因为如果您依赖casc,该国可能有许多记录,并导致大量用户锁定