如何在 SQL 中表示订单内容

How to represent order content in SQL

我正在创建一个披萨配送网站,我需要在数据库中的某处表示订单及其内容。

问题是,我完全不知道如何存储物品及其数量。

我的第一个想法是创建一个 order_content table,其中包含订单 ID 作为外键,并且有两个额外的列:项目 ID 和数量。

另一个问题:我有多种类型的物品:比萨饼、饮料、附加品等...所以 id 在不同类别中不是唯一的。我不能只说,例如在 order_content item_id 1 中,数量 1,因为 item_id 1 可能意味着 id 为 1 的饮料,披萨id 1 等...

另一个大问题:我有一个定制的比萨饼,它可以包含 3 到 6 种定制成分。我在 table 中有配料及其唯一 ID...我如何在订单中表示此自定义比萨饼?

谢谢

PS : 我是 SQL - 关系数据库

的初学者

您可能想查看 事实 table维度 table 定义。一旦理解了这个概念,您就会清楚订单 table 将是一个 事实 table,并且 table 等成分将是一个 维度 table.

一般来说,购物网站的存储系统都是利用订单和订单行之间的关系。

您可以像这样组织您的数据库并回答您的问题

order order_line product ingredient ingredient_for_product
id order_id product_id ingredient_id ingredient_id
... quantity current_unit_price name order_line_id
unit_price product_type additional_price quantity
product_id

product 是一个抽象概念,包含贵公司所有已售出的产品。如果您需要更精确,您可以添加将根据 product_type 的值完成的字段,或者创建另一个带有 [=37 的 table =] 与产品的关系 table.

你有一个 unit_price order_line table 和一个 current_unit_price 在产品中 table.

这有两个用途:

  1. 如果您事后更改产品价格,您仍将保持客户支付的价格
  2. 它允许您存储与您注册的“current_unit_price”不同的价格。例如添加辅助成分的值

这是您应该试验并修改以满足您的需要的架构。

create table clients(
  id serial,
  name varchar(25) not null,
  email varchar(25) not null,
  telephone varchar(25),
  constraint pk_clients_id primary key (id),
  constraint uq_clients_email unique(email)
  );
create table items(
  id serial,
  name varchar(25),
  price decimal(5,2),
  constraint pk_items_id primary key (id) 
  );
create table orders(
  id serial,
  client_id int,
  constraint pk_orders_id primary key (id),
  constraint fk_orders_client foreign key (client_id) references clients(id)
  );
create table toppings(
  id serial, 
  name varchar(25) not null,
  constraint pk_topping primary key (id));
create table order_details(
  order_id int, 
  item_id int,
  quantity int,
  topping_1 int,
  topping_2 int,
  topping_3 int,
  topping_4 int,   
  topping_5 int,
  topping_6 int,
  constraint fk_order_details_order_id foreign key (order_id) references orders(id),
  constraint fk_custom_pizza_id foreign key (item_id) references items(id),
  constraint pk_order_details_order_item_ids primary key(order_id, item_id)
  );
✓

✓

✓

✓

✓
insert into clients (name, email, telephone) values ('Andrew','andrew@gmail.com','0123456789');
insert into items (name, price) values('custom pizza','20.00'),('1.5 litre coca-cola',5);
insert into toppings (name) values('mozzarella'),('parma ham'),('mushrooms'),('olives'),('red peppers'),('salmon');

1 行受影响

2 行受影响

6 行受影响

with order_number as
(insert into orders (client_id) values (1)
returning id)
insert into order_details 
select order_number.id,1,1,1,2,3,4,5,6 from order_number
union all
select order_number.id,2,1,null,null,null,null,null,null from order_number;

2 行受影响

select 
c.id,
c.name,
o.id order_number,
od.item_id,
i.name,
i.price,
od.quantity * i.price as line_total,
t1.name topping_1,
t2.name topping_2,
t3.name topping_3,
t4.name topping_4,
t5.name topping_5,
t6.name topping_6
from clients c
left join orders o on c.id = o.client_id
left join order_details od on o.id = od.order_id
left join items i on od.item_id = i.id
left join toppings t1 on od.topping_1 = t1.id
left join toppings t2 on od.topping_2 = t2.id
left join toppings t3 on od.topping_3 = t3.id
left join toppings t4 on od.topping_4 = t4.id
left join toppings t5 on od.topping_5 = t5.id
left join toppings t6 on od.topping_6 = t6.id
id | name   | order_number | item_id | name                | price | line_total | topping_1  | topping_2 | topping_3 | topping_4 | topping_5   | topping_6
-: | :----- | -----------: | ------: | :------------------ | ----: | ---------: | :--------- | :-------- | :-------- | :-------- | :---------- | :--------
 1 | Andrew |            1 |       1 | custom pizza        | 20.00 |      20.00 | mozzarella | parma ham | mushrooms | olives    | red peppers | salmon   
 1 | Andrew |            1 |       2 | 1.5 litre coca-cola |  5.00 |       5.00 | null       | null      | null      | null      | null        | null     

db<>fiddle here