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

问题描述 投票:0回答:3

我只是学习使用关系数据库,所以我的知识有限。我有数据点,依赖于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。我如何设计表格以提供规范化?

先感谢您。

sql relational-database database-normalization
3个回答
1
投票

你可能想要4张桌子。

1表存储最小和最大年龄(事实上每个范围)

1表存储值x

1个表存储产品名称(以及其他一些信息)

表年龄,值x和产品名称之间的1个关系表,存储它们的外键加上价格。该表的主键是所有FK的组成,以确保唯一的数据。

我实际上正在编写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   |

Listing of all tables content

查询#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


1
投票

这些关系可能适合:

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


1
投票

基本上,你会有4个表。

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

由于每个产品都有不同的年龄范围和x值,因此这些表还应具有引用products表的外键。

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

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)
)
© www.soinside.com 2019 - 2024. All rights reserved.