mysql - 对桥接实体和多属性实体感到困惑
问题描述
我只是有几个我很困惑的问题。我无法让我的 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.如何创建桥接实体?所以我的桥实体称为购买,我将如何做到这一点?我在网上看了,但我看到的只是选择语句。
我将如何创建多值属性?就像客户的名字一样,这是一个多值属性
我还应该在主键中包含 NOT NULL 吗?我正在考虑在客户姓名中添加 NOT NULL。
解决方案
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
推荐阅读
- sql - 将空值替换为列中的值
- javascript - 如何在盖茨比中检查前面的内容是否为空
- java - 如何使用散点图 JavaFX 将符号变成圆形?
- apache - 您可以使用重写规则使所有子文件夹成为子域吗?
- ruby-on-rails - 如何使用friendly_id 查找产品?
- xslt - XSLT 元素到新元素中的属性
- r - 如何从要在循环中使用的数据框中提取列的名称?
- console - 我们如何将汉字集成到控制台端的 qpython 3 中,就像它在解释器端一样?
- python - 运行 xlwings 和 win32com.client 时出错
- python - Python 使用 datetime 和 timedelta 返回 datetime 对象