AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 148530
Accepted
AndreKR
AndreKR
Asked: 2016-09-02 02:29:26 +0800 CST2016-09-02 02:29:26 +0800 CST 2016-09-02 02:29:26 +0800 CST

我将使用 MATCH SIMPLE 外键做什么?[复制]

  • 772
这个问题在这里已经有了答案:
MATCH FULL、MATCH SIMPLE 和 MATCH PARTIAL 之间的区别? (2 个回答)
3年前关闭。

我的理解:

除了对被引用表的有效引用之外,还允许具有外键的列包含 NULL 值。SQL 标准为外键定义了几种匹配模式,例如 MATCH SIMPLE 和 MATCH FULL。对于多列外键,只要外键的至少一列包含 NULL 值,MATCH SIMPLE 就允许任何列中存在错误(= 不引用)值。

多列外键很少见(因为多列主键是),但我可以想象有效的用例。例如,博客文章的翻译可能有一个主键(post_id, language_id)。现在,引用此类翻译的内容(例如用户当前正在编辑的翻译)将具有多列外键。

我不明白的是:

为什么我会使用 MATCH SIMPLE 作为我的外键?

在上面的示例中,有一个仅引用 bypost_id而不是 by的“当前正在编辑”条目是没有意义的language_id。

什么是有意义的例子?

foreign-key constraint
  • 3 3 个回答
  • 3505 Views

3 个回答

  • Voted
  1. nvogel
    2016-09-02T03:51:10+08:002016-09-02T03:51:10+08:00

    我的偏好是避免在外键列中出现空值。使所有外键不可为空。事实上,在我用于验证数据库设计的一些静态分析脚本中,我有外键 = not null 作为标准检查。

    FULL / SIMPLE 行为非常模糊,以我的经验,即使专家也不总是能理解它(我是专家,我必须三思而后行!)正如 ypercube 指出的那样,SIMPLE 实际上是 Microsoft SQL Server 中的默认设置但我怀疑大多数使用该产品的人甚至从未考虑过它。如果您在数据库设计中的目标之一是使数据能够被普通用户理解和使用,那么外键应该是不可为空的。

    • 3
  2. ypercubeᵀᴹ
    2016-09-02T02:47:11+08:002016-09-02T02:47:11+08:00

    对于多列外键,MATCH SIMPLE只要至少一列外键包含一个值,就允许在任何列中出现错误(= 不引用)NULL值。

    不完全是。NULL如果行具有值,则所有外键约束都允许行“错误”(不引用) 。MATCH FULL例如将允许(NULL, NULL)两列外键中的一行。这对我来说也没有多大意义。唯一的区别是 - 正如你所提到的 - 这MATCH SIMPLE将允许(post_id_value, NULL), (NULL, language_id_value)rows 而MATCH FULL不会。

    我在网站上看到了一些问题,其中MATCH SIMPLE一个值是空的(有些)是有意义的。这些案例通常有一些非规范化的设计。在您的示例中,它看起来像是历史表中的一个额外外键,仅使用两列之一:

     (post_id) REFEERNCES post (post_id)
    

    这将允许历史表在两个值都不为空时引用翻译表,而当 language_id 为空时引用后表。我自己从来不会使用它,但我见过它。

    现在,抛开这些奇怪的情况,如果所有列都用 定义,则两个选项 (MATCH FULL和) 是相同的。而且由于通常在外键中有不可为空的列,并且此设置仅影响多列外键,我想这就是为什么许多设计人员通常不担心此设置并将其保留为 DBMS 的默认设置(在 Postgres 中) .MATCH SIMPLENOT NULLMATCH SIMPLE

    所以,对于你的问题:

    为什么我会使用MATCH SIMPLE我的外键?

    我可以反问:

    为什么我会使用NULL我的外键列?

    另请注意,大多数 DBMS 并未实现 SQL 标准提供的所有选项。Postgres 没有MATCH PARTIAL,SQL Server 根本没有选项(所有外键都表现为MATCH SIMPLE)。

    • 1
  3. Best Answer
    Renzo
    2016-09-02T13:03:56+08:002016-09-02T13:03:56+08:00

    你在问:

    什么是有意义的例子?

    这是一个非常简单的例子:

    create table student(snum integer primary key,
                         name text);
    create table course(cnum integer primary key,
                        title text);
    create table exam (snum integer references student,
                       cnum integer references course,
                       mark integer check (mark >=1 and mark <= 10),
                       primary key(snum, cnum));
    create table info (snum integer,
                       cnum integer,
                       info text,
                       foreign key (snum) references student,
                       foreign key (cnum) references course,
                       foreign key (snum, cnum) references exam match simple,
                       check (snum is not null or cnum is not null));
    insert into student values (1, 'john'), (2, 'mary'), (3, 'lucy');
    insert into course values (1, 'programming'), (2, 'database');
    insert into exam values (1, 1, 10), (1, 2, 8), (3, 1, 6), (3, 2, 9);
    insert into info values (1, null, 'info about student 1'), 
                            (null, 2, 'info about course 2'), 
                            (1, 1, 'info about exam of student 1 in course 1');
    

    在此示例中,该表info维护有关学生、课程和考试的信息,我们希望这些信息保持一致。没有match simple这个是不可能的。请注意,但是会检查外键:

    insert into info values (2, 2, 'info about exam of student 2 in course 2');
    
    ERROR: insert or update on table "info" violates foreign key constraint "info_snum_fkey1"
    SQL state: 23503
    Detail: Key (snum, cnum)=(2, 2) is not present in table "exam".
    

    最后,请注意,在上面的示例中,您必须至少指定一个学生或一门课程;

    insert into info values (null, null, 'nonsense information');
    
    ERROR:  new row for relation "info" violates check constraint "info_check"
    DETAIL:  Failing row contains (null, null, nonsense information).
    
    • 1

相关问题

  • 删除/更新外键约束中 SET NULL 的目的是什么?

  • 固定值字段的外键约束

  • 使字段唯一会使其被索引吗?

  • 非唯一多列外键

  • 外键违规 - 不知道为什么

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve