比为每行创建新表更好的方法

时间:2017-11-11 07:47:37

标签: mysql sql

旧数据表:

enter image description here

我想知道是否有其他方法来优化这个,或者是否有不同的方法将这两个表以某种方式连接在一起。

对于我的第一个项目,这就是我(多年前)接近它的方式,现在我遇到了一个类似的问题,我想知道我以前做过的是最好的...因为我是某种程度上有疑虑(有点直觉,我做错了)。我已经很长时间没有完成SQL了,所以我的思考过程似乎没有为这个问题做好。

当前数据表:

enter image description here

我的问题是,如何创建产品的过程与其他产品的制作方式不同,完成任务/过程的时间也不相同。

所以我的问题是,这是解决这个问题的最佳方法吗?如果没有,你介意分享一些关于如何解决这个问题的见解吗?

1 个答案:

答案 0 :(得分:1)

为每个产品创建单独的表是一个糟糕的设计。 如果你有10000个产品,你必须有10001个表,这是噩梦。一些缺点:

  • 预计会很慢
  • 如果要向此结构添加新列,则需要更改10000个表
  • 针对此架构的一些非常基本的查询实际上是写不出来的,例如给我所有产品,其中Melting proccess是1:00 给我一个平均的铸造过程时间给所有人产品

通常只需创建2个表并使用Foreign Key即可解决

一个非常简单的例子:http://sqlfiddle.com/#!9/e8175b/4(它是杂乱的 - 错误的数据类型,缺少索引,缺少约束等但显示了这个想法):

CREATE TABLE product(
   pid int primary key,
   ProductName varchar(200)
);

INSERT INTO product VALUES
( 1, 'Earning001' ),( 2, 'Earning002' ),( 3, 'Necklerace001' );

CREATE TABLE Times(
  product_pid int,
  process varchar(100) not null,
  timetoaccomplish varchar(10) not null,
  constraint times_pid_kf foreign key (product_pid) references product(pid)
);

INSERT INTO Times VALUES
(1, 'Melting', '1:00'),(1, 'Casting', '2:00'),(1, 'Polishing', '0:20'),
(2, 'Melting', '1:20'),(2, 'Casting', '1:30'),(2, 'Polishing', '0:40'),
(3, 'Melting', '5:20'),(3, 'Casting', '2:15'),(3, 'Polishing', '1:45');
select * from Product;

| pid |   ProductName |
|-----|---------------|
|   1 |    Earning001 |
|   2 |    Earning002 |
|   3 | Necklerace001 |
select * from Times;

| product_pid |   process | timetoaccomplish |
|-------------|-----------|------------------|
|           1 |   Melting |             1:00 |
|           1 |   Casting |             2:00 |
|           1 | Polishing |             0:20 |
|           2 |   Melting |             1:20 |
|           2 |   Casting |             1:30 |
|           2 | Polishing |             0:40 |
|           3 |   Melting |             5:20 |
|           3 |   Casting |             2:15 |
|           3 | Polishing |             1:45 |
select * 
from product p
join Times t
on p.pid = t.product_pid;

| pid |   ProductName | product_pid |   process | timetoaccomplish |
|-----|---------------|-------------|-----------|------------------|
|   1 |    Earning001 |           1 |   Melting |             1:00 |
|   1 |    Earning001 |           1 |   Casting |             2:00 |
|   1 |    Earning001 |           1 | Polishing |             0:20 |
|   2 |    Earning002 |           2 |   Melting |             1:20 |
|   2 |    Earning002 |           2 |   Casting |             1:30 |
|   2 |    Earning002 |           2 | Polishing |             0:40 |
|   3 | Necklerace001 |           3 |   Melting |             5:20 |
|   3 | Necklerace001 |           3 |   Casting |             2:15 |
|   3 | Necklerace001 |           3 | Polishing |             1:45 |

一个简单的查询:向我提供流程为Casting且时间至少为2:00的所有产品

select * 
from product p
join Times t
on p.pid = t.product_pid
WHERE t.process = 'Casting'
  AND t.timetoaccomplish >= '2:00'

| pid |   ProductName | product_pid | process | timetoaccomplish |
|-----|---------------|-------------|---------|------------------|
|   1 |    Earning001 |           1 | Casting |             2:00 |
|   3 | Necklerace001 |           3 | Casting |             2:15 |