【问题标题】:Foreign key from events table 1-1 0r many?来自事件表 1-1 0r 的外键很多吗?
【发布时间】:2015-08-14 02:44:55
【问题描述】:

我可能在这里过度思考了一个问题,很可能会被否决,但我已准备好接受打击。我正在数据仓库中构建我的第一个模式。

2 表:事件和联系人:

events(id(pk), cid, other, fields, here)
contacts(id (pk), cid(fk), other, fields, here)

有人访问我们的网站并注册。在事件列“id”中生成一个行项目,并为联系人生成一个“cid”。一条新记录被添加到联系人中。

我有两个问题:

  1. 我可以将联系人的主键设置为 cid 吗?所以主键也是外键?
  2. 我正在使用 MySQL Workbench 创建架构。当我创建联系人表时,我可以将 cid 的外键和基数设置为 1-1 或 1-many。从联系人表的角度来看,关系是 1-1 还是 to many?联系人中只会有 1 条 cid 记录,但如果该用户执行多项操作(例如接收来自我们的电子邮件等),它们将在事件表中出现多次。所以,逻辑上是 1-many。但是当在 Workbench 中创建它时,关系线看起来好像是一对多的关系,其中许多部分在联系人处,而不是根据需要反过来。应该反过来吧?

events.cid和contacts.cid是什么关系?

【问题讨论】:

    标签: database-schema


    【解决方案1】:

    如果用户的注册导致单个contact_ 记录,而每个用户访问网站(每个会话启动)都会导致属于该用户的contact_ 记录的event_ 记录,那么您有一个One-多对多关系。

    `contact_` = parent table (the One)
    `event_` = child table (the Many)
    

    请注意我是如何将这种关系归结为一个句子的。在进行分析工作以确定表结构时,这应该是您的目标。

    关系几乎总是被定义为从父表上的主键到子表上的外键的链接。

    如何定义primary key 取决于您。首先决定您想要natural key 还是surrogate key。以我的经验,自然键永远不会起作用,因为值总是最终会改变。

    如果使用代理键,请确定什么类型。通常的选择是绑定到自动递增序列生成器的整数,或UUID。如果曾经federating data 与其他数据库或系统一起使用,那么 UUID 就是要走的路。如果使用整数,请确定大小,32-bit 整数处理总共 2-40 亿条记录。一个 64-bit 整数可以跟踪 18 个 quintillion 记录。

    子表中的外键只是其分配的父主键值的副本。因此外键必须与父主键具有相同的数据类型。

    如果特定父记录在子表中拥有多条记录,则这些子记录中的每一个都将携带该父记录的主键副本。因此,如果用户 Susan 有五个事件,则她的主键值在 contact_ 表中出现一次,并且相同的值在存储在外键列中的 event_ 表中出现五次。

    如果 cid 在所有其他 contact_ 记录中唯一标识每个 contact_ 记录,则您有一个主键。无需定义另一个。

    【讨论】:

    • 嗨@Basil 感谢您的彻底回复。我将使用contact.cid 作为联系人表中的主键,然后将其作为事件表中的外键。当我发布我的问题时,我认为我的情况正好相反。在我看来,事件首先发生,并且在初始事件的后面生成了一个 cid,从而导致了一个新的联系记录,因此从那个 pov 我认为事件表是父级。
    • 关于帐户创建:标记特定的“event_”记录。也许“event_”表有一个“type_”列,您在其中存储“帐户创建”。或“summary_”和“detail_”列,其中“summary_”包含“帐户创建”短语,“detail_”包含各种其他信息,例如日期时间、他们的 IP 地址或其他信息。如果非常重要,请在“event_”上添加一个布尔列“account_creation_”,可能已编入索引。换句话说,帐户创建并不特殊,它只是可能发生的几种类型的事件之一,例如“已发送电子邮件”、“已支付账单”、“已发布推文”。
    • 如果您的业务规则规定创建“contact_”行总是涉及创建至少一个标记为“帐户创建”的“event_”行,那么@987654329图中的@应该改变。该图显示:每个“contact_”行可以有 个或多个“event_”子级。但根据该业务规则,它应该是:每个“contact_”行可以有 一个 或多个“event_”子级(从不为零)。
    • 嗨@Basil 好的,非常感谢。是的,会有一个 event_type 字段,并且现在有一个帐户创建事件听起来非常明显,所以我可以过滤它进行分析。同样,这是我的第一个模式!关于 SQL Workbench 中的“鱼尾纹”,这似乎用一个条形显示,所以我相信这确实意味着 1 个或更多
    • 鱼尾纹符号从来没有标准化过。所以存在变异。我更喜欢单条来表示“只有一个”,而其他人则使用双条。大概在双条中,第一个条替换零+条中的零,这意味着“零或一”,如我的评论链接所示。
    猜你喜欢
    • 1970-01-01
    • 2015-11-08
    • 2019-10-27
    • 1970-01-01
    • 2015-01-31
    • 2010-09-07
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多