首页 > 解决方案 > 对桥接实体和多属性实体感到困惑

问题描述

我只是有几个我很困惑的问题。我无法让我的 er 图表出现在这篇文章中,所以我不得不创建它的“文本”版本。

Entity: customers
    Attributes: 
                cus_id -- primary key
                cus_fname -- multi-attribute (name)
                cus_lname -- multi-attribute (name)
                cus_gender -- multi-attribute (name)
                cus_dob

Entity: products
    Attributes:
                prod_id -- primary key
                prod_name
                prod_cost
                prod_retail

Bridge Entity: buys
    Attributes:
                prod_id
                cus_id
---------------------------------------

CREATE TABLE customers (
    cus_id        NUMBER(5,0)
                  CONSTRAINT cus_id_pk
                  PRIMARY KEY (cus_id),
    cus_fname     VARCHAR2(32),
    cus_mname     VARCHAR2(32),
    cus_lname     VARCHAR2(32),
    cus_gender    NUMBER(1,0),
    cus_dob       DATE
);
-----------------------------------------
CREATE TABLE products (
    prod_id       NUMBER(5,0)
                  CONSTRAINT cus_id_pk
                  PRIMARY KEY (cus_id),
    prod_name     VARCHAR2(32),
    prod_cost     NUMBER(4,2),
    prod_retail   NUMBER(4,2)
);

1.如何创建桥接实体?所以我的桥实体称为购买,我将如何做到这一点?我在网上看了,但我看到的只是选择语句。

  1. 我将如何创建多值属性?就像客户的名字一样,这是一个多值属性

  2. 我还应该在主键中包含 NOT NULL 吗?我正在考虑在客户姓名中添加 NOT NULL。

标签: mysqlsqldatabasecreate-table

解决方案


buys称为关联表、连接表、关系表或任何其他数量的名称。我不会将它称为“实体”,除非它确实是您系统中的一个实体(代表一个人、地点、事物概念或事件,可以唯一标识,对业务感兴趣,并且我们可以存储相关信息。)

关联表的表定义可能如下所示:

CREATE TABLE buys
( prod_id  NUMBER(5,0) NOT NULL COMMENT 'composite PK, FK ref products.prod_id'
, cus_id   NUMBER(5,0) NOT NULL COMMENT 'composite PK, FK ref customers.cus_id'
, PRIMARY KEY (prod_id, cus_id) 
, UNIQUE KEY buys_UX1 (cus_id, prod_id)
, CONSTRAINT FK_buys_products FOREIGN KEY (prod_id) REFERENCES products (prod_id) 
  ON DELETE CASCADE ON UPDATE CASCADE     
, CONSTRAINT FK_buys_customers FOREIGN KEY (cus_id) REFERENCES customers (cus_id) 
  ON DELETE CASCADE ON UPDATE CASCADE     
) ENGINE=InnoDB
;

注意:我不相信这NUMBER(5,0)是一个有效的 MySQL 数据类型。对于主键列,我倾向于使用整数数据类型,INT或者BIGINT. 但是外键列必须与引用的主列的数据类型完全匹配,所以我将其用作NUMBER(5,0)引用列的数据类型的副本。


多值属性可以实现为子表,一对多关系。但我在模型中没有看到任何多值属性的迹象。

复合属性可以实现为单独的表。但我不会去那里,除非有一个用例使它变得有利。

我个人对处理复合属性的偏好是简单地为列名添加前缀。例如,作为这些列是属性“名称”的组成部分的指示......

 cus_name_title
 cus_name_last
 cus_name_first
 cus_name_suffix

同样,对于“邮寄地址”属性

cus_addr_street
cus_addr_line2
cus_addr_city
cus_addr_state
cus_addr_postal_code

(其他一些关系数据库支持声明复合“类型”;我不相信这个功能在 MySQL 中可用。(而且我不会选择将复合属性表示为 JSON 对象。)

PRIMARY KEY约束已经对主键中的所有列强制执行 NOT NULL。但是也明确地包含NOT NULL约束并没有什么坏处。我的偏好是NOT NULL在我们不想接受 NULL 值的任何列上添加约束。

跟进

对于实体的多值属性(单个实例可以具有零、一个或多个值的属性),常见模式是子表。以客户电话号码为例。

我们可以使用外键创建表,引用客户中的 cus_id。

 CREATE TABLE cus_phone_numbers 
 ( id            INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'PK'
 , cus_id        NUMBER(5,0) NOT NULL COMMENT 'FK ref customers.cus_id'
 , phone_type    VARCHAR(80)  COMMENT 'e.g. main, mobile, office, fax'
 , phone_number  VARCHAR(80)
 , CONSTRAINT FK_cus_phone_numbers_customers 
   FOREIGN KEY (cus_id) REFERENCES customers (cus_id)
   ON DELETE CASCADE ON UPDATE CASCADE
 ) ENGINE=InnoDB 
 ;

例如,具有三个电话号码的客户将在电话号码表中具有三行。没有电话号码的客户在表中将有零行。

  cus_id   phone_type    phone_number
  ------   ----------    ---------------
      42   main 1        xxx-xxx-1111
      42   office        xxx-xxx-1212
      42   fax           xxx-xxx-3333
     112   service       xxx-xxx-7701
     112   delivery      xxx-xxx-7702

那是多值属性……以及可以具有零、一个或多个值的实体的属性。


一个复合属性由几个组件属性组成。例如,客户“姓名”属性可以是几个简单属性的组合:

 title/salutation        'Major'
 first name              'Charles'
 middle name             'Emerson'
 last name               'Winchester'
 suffix                  'III'
 nickname                ''

总是可以将实体的某些属性拆分到单独的表中,无论这些是简单属性还是复合属性。我们这样做的最常见原因之一是支持多个值。但我们也可以对单值属性执行此操作。

考虑“电话号码”属性。这可以建模为复合属性:

country code        +1
area code           888
exchange number     467
line number         4355

推荐阅读