如何处理 SQL 中的多维矩阵?

How to handle multi dimensional matrices in SQL?

我刚开始学习使用关系型数据库,所以知识有限。我有依赖于 3 个值的数据点:产品类型、年龄和值 x。 因此,对于每种产品类型,都有一个矩阵,从中可以根据年龄和价值 x 获得价格。

产品 A

         Value x
Age                 0 - 18    19 - 64    65 - 150
         50          5.6        6.3        3.5
         100         5.2        3.5        6.3
         200         6.4        3.7       12.3
         500         3.9        2.3        5.5

其中有几种产品。 x 的值和年龄范围可以变化。

因此产品的价格取决于产品类型、使用年限和价值 x。我想如何设计表以提供规范化?

提前致谢。

这些关系可能适合:

Product(name,*ID*) 
Relation (*product_ID,type_id,age_id,value_X_id*) FK product_id references product, type references types, age references ages, valueX references value_2s
ValueXs(*ID*, value)
Type2(*ID*, value)
Age(*ID*, value)

这是完全规范化的形式,注意:strarred qoutas下划线是什么ID

您可能需要 4 tables。

1 table 存储最小和最大年龄(实际上是每个范围)

1 table 存储值 x

1 table 存储产品名称(和一些其他信息)

1 table table 年龄、价值 x 和产品名称之间的关系,存储它们的外键加上价格。这个table的主键是所有外键的组合,保证数据唯一

我实际上正在编写 SQL 代码来为您提供示例。

架构(MySQL v5.7)

CREATE TABLE age
(
  id INT(6) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  min_age INT(6) NOT NULL,
  max_age INT(6) NOT NULL
);

CREATE TABLE valuex
(
  id INT(6) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  val INT(6) NOT NULL
);

CREATE TABLE products
(
  id INT(6) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL
);

CREATE TABLE pricing
(
  age_id INT(6) NOT NULL,
  valuex_id INT(6) NOT NULL,
  products_id INT(6) NOT NULL,
  price DECIMAL(5, 2) NOT NULL,
  FOREIGN KEY (age_id) REFERENCES age(id),
  FOREIGN KEY (valuex_id) REFERENCES valuex(id),
  FOREIGN KEY (products_id) REFERENCES products(id),
  PRIMARY KEY (age_id, valuex_id, products_id)
);

INSERT INTO age VALUES (default, 0, 18), (default, 19, 64 ), (default, 65, 150);
INSERT INTO valuex VALUES (default, 5), (default, 100), (default, 200), (default, 500);
INSERT INTO products VALUES (default, "A");

INSERT INTO pricing VALUES (1, 1, 1, 5.6),
                           (2, 2, 1, 6.3),
                           (3, 3, 1, 3.5),
                           (1, 4, 1, 5.2),
                           (2, 1, 1, 3.5),
                           (3, 2, 1, 6.3),
                           (1, 3, 1, 6.4),
                           (2, 4, 1, 3.7),
                           (3, 1, 1, 12.3),
                           (1, 2, 1, 3.9),
                           (2, 3, 1, 2.3),
                           (3, 4, 1, 5.5);

查询#1

-- Get all prices for product A
SELECT CONCAT(a.min_age, ' - ',a.max_age) AS "Age range",
       v.val AS "Value x",
       pr.name AS "Product Name",
       p.price AS "Price"
FROM pricing p
LEFT JOIN age a
ON a.id = p.age_id
LEFT JOIN valuex v
ON v.id = p.valuex_id
LEFT JOIN products pr
ON pr.id = p.products_id
WHERE pr.name = "A";

输出

| Age range | Value x | Product Name | Price |
| --------- | ------- | ------------ | ----- |
| 0 - 18    | 5       | A            | 5.6   |
| 0 - 18    | 100     | A            | 3.9   |
| 0 - 18    | 200     | A            | 6.4   |
| 0 - 18    | 500     | A            | 5.2   |
| 19 - 64   | 5       | A            | 3.5   |
| 19 - 64   | 100     | A            | 6.3   |
| 19 - 64   | 200     | A            | 2.3   |
| 19 - 64   | 500     | A            | 3.7   |
| 65 - 150  | 5       | A            | 12.3  |
| 65 - 150  | 100     | A            | 6.3   |
| 65 - 150  | 200     | A            | 3.5   |
| 65 - 150  | 500     | A            | 5.5   |

所有 table 内容的列表

查询#2

SELECT * FROM age;

| id  | min_age | max_age |
| --- | ------- | ------- |
| 1   | 0       | 18      |
| 2   | 19      | 64      |
| 3   | 65      | 150     |

查询 #3

SELECT * FROM valuex;

| id  | val |
| --- | --- |
| 1   | 5   |
| 2   | 100 |
| 3   | 200 |
| 4   | 500 |

查询#4

SELECT * FROM products;

| id  | name |
| --- | ---- |
| 1   | A    |

查询 #5

SELECT * FROM pricing;

| age_id | valuex_id | products_id | price |
| ------ | --------- | ----------- | ----- |
| 1      | 1         | 1           | 5.6   |
| 1      | 2         | 1           | 3.9   |
| 1      | 3         | 1           | 6.4   |
| 1      | 4         | 1           | 5.2   |
| 2      | 1         | 1           | 3.5   |
| 2      | 2         | 1           | 6.3   |
| 2      | 3         | 1           | 2.3   |
| 2      | 4         | 1           | 3.7   |
| 3      | 1         | 1           | 12.3  |
| 3      | 2         | 1           | 6.3   |
| 3      | 3         | 1           | 3.5   |
| 3      | 4         | 1           | 5.5   |

View on DB Fiddle

基本上,你会有 4 tables。

一个会包含产品信息,
其中一个将包含年龄范围(注意:这假设每个产品的年龄范围相同)
一个将包含 X 个值,
最后一个将包含价格,使用我之前列出的 3 tables 的外键。

由于每个产品的年龄范围和 x 值不同,因此这些 table 也应该有引用产品 table 的外键。

像这样的事情应该让你开始:

create table products 
(
    id int primary key,
    name varchar(100)
    -- other product related details such as description ans stuff
);

create table ageRanges
(
    product_id int foreign key references products(id),
    id int primary key,
    name varchar(100)
)

create table X
(
    product_id int foreign key references products(id),
    value int
)

create table prices
(
    product_id int foreign key references products(id),
    ageRange_id int foreign key references ageRanges(id), 
    x_id int foreign key references X(id), 
    price numeric(10, 2)
)