创建订单表
学习创建另一张具有适当属性和约束的表。
简介
我们将继续构建一个简单的客户关系管理系统。目前已经创建了 customers 和 products 表,现在准备创建另外两张表:orders 和 order_items。
模型详情
orders 表用于存储订单的主信息:
- 通过
customer_id列引用所属的customer。这是一个外键。根据一个订单,可以唯一确定其对应的客户,因此订单到客户之间是多对一关系。而反过来,一个客户可以拥有多个订单,因此客户与订单之间是一对多的关系。 - 此外,
orders表还包含order_number。该字段为必填项,以字符串形式表示,如ORD123,且必须唯一。不允许两个或多个订单具有相同的order_number。该字段将用于快速通过编号查找订单。 - 我们使用
ordered_at字段记录订单创建的日期和时间,该字段也是必填项。
order_items 表用于存储订单的明细信息。由于每条记录都属于某个订单,因此有以下设计:
- 需要
order_id列来引用所属的订单,这也是数据库中的一个外键。根据一个订单项,可以唯一定位到它所属的订单,因此订单项到订单之间是多对一关系;而一个订单可以包含多个订单项,因此订单与订单项之间是一对多关系。 - 每个订单项还需要明确指向所关联的产品,因此存在另一个外键
product_id,用于引用具体的产品。订单项到产品之间是多对一关系,而产品到订单项之间是一对多关系。 order_items表还包含一个price字段,类型为数值,共 15 位数字,其中 2 位小数。该字段记录下单时该产品的销售价格,是必填项。
出于教学目的,我们决定禁止同一订单中出现重复的产品。如果某个订单包含同一产品多次,则应通过一个订单项来表示,其 quantity 字段等于该产品在订单中的数量。
那么,如何让关系型数据库管理系统(RDBMS)帮助实现这一约束?或许可以通过唯一索引?但不能仅对 order_items 表的 product_id 建立唯一性约束,因为这会阻止同一产品出现在不同订单中。因此,唯一性必须基于 product_id 与 order_id 的组合。我们将在后续介绍如何创建这样的唯一索引。
orders 表
首先,通过以下查询查看当前数据库中已有的表数量:
1show tables;
目前已有两张表:customers 和 products。
接下来创建 orders 表,创建命令如下:
1create table orders (id int(11) not null auto_increment, order_number varchar(255) not null, ordered_at datetime not null, customer_id int(11) not null, primary key (id));
在执行此命令前,请注意这里有一个新内容:datetime 类型被用于 ordered_at 字段。该类型用于存储包含日期和时间的时间戳数据。
我们还将再次使用 show tables 查询来列出所有表:
1create table orders (id int(11) not null auto_increment, order_number varchar(255) not null, ordered_at datetime not null, customer_id int(11) not null, primary key (id)); 2show tables;
输出显示 orders 表已成功创建。下面我们查看该表的实际结构:
11 mysql> show create table orders; 22 +--------+---------------------+ 36 | Table | Create Table | 410 +--------+--------------------+ 514 | orders | CREATE TABLE `orders`( 615 `id` int(11) NOT NULL AUTO_INCREMENT, 716 `order_number` varchar(255) COLLATE utf8_unicode_ci NOT NULL, 817 `ordered_at` datetime NOT NULL, 918 `customer_id` int(11) NOT NULL, 1019 PRIMARY KEY (`id`) 1120 )ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8_unicode_ci 1221 +--------+--------------------+
目前这张表缺少一项关键功能:无法在物理层面与 customers 表建立连接。虽然已有 customer_id 列,但它在数据库层面未施加任何约束或规则。换句话说,MySQL 并不知道 orders 表与 customers 表之间存在关联。