Relational db如何存储复杂的逻辑关系?
Relational db how to store complex logical relations?
例如,我们有一个系统可以让用户根据他们参加的活动索取 X 份礼物。
事件table:
| id | name |
----------------
| A | event A |
| B | event B |
礼物table:
| id | name | formula |
--------------------------
| 1 | dog | A*1 + B*2 |
| 2 | cat | (A|B)*3 |
在礼物table中我们有一些公式:
A*1 + B*2
- 参加活动A可获得1个玩具,参加活动B可再获得2个玩具。
(A|B)*3
- 参加活动A或B的用户可以获得3个玩具。
公式在后端计算,但我想知道我们是否可以以某种方式在数据库中表示 event
和 gift
的关系?具体来说,我们希望:
SQL SELECT
event
基于 gift
,反之亦然
- 跟踪用户在每个
event
. 上声称 gift
基地的次数
非常感谢您
您需要的是一个桥接 table (associative entity),用于记录哪些用户访问过哪些事件。这看起来像下面这样:
User_Events
:
User_ID | Event_ID
------------------
1 | 1
1 | 2
2 | 2
请注意,每个值代表相关 table 中的一个外键 (id
)。
从这里,您可以应用基于 'events that the user has been to' 的逻辑,方法是查询如下内容:
SELECT E.*
FROM Users U
JOIN Events E
ON User_Events.User_ID = User_Events.Event_ID
您可以使用 many-to-many 关系 table 来表示礼物和事件之间的关系以及用户对礼物的要求:
CREATE TABLE event_gifts
(
id int PRIMARY KEY AUTO_INCREMENT,
event_id text REFERENCES event(id),
gift_id int REFERENCES gift(id)
);
CREATE TABLE event_gift_claim
(
id int PRIMARY KEY AUTO_INCREMENT,
user_id INT REFERENCES user(id),
event_gift_id INT REFERENCES event_gifts (id)
);
然后您可以跟踪事件和礼物之间的关系:
INSERT INTO event_gifts (event_id, gift_id)
VALUES
('A', 1),
('A', 2),
('B', 1),
('B', 2);
和select奖励特定礼物的事件:
SELECT event.*
FROM event
JOIN event_gifts
ON event_gifts.event_id = event.id
JOIN gift
ON gift.id = event_gifts.gift_id
WHERE gift.name = 'dog'
(或者反过来,来自活动的礼物)
您可以追踪谁声明了什么:
INSERT INTO event_gift_claim (user_id, event_gift_id) VALUES
(1, 1), -- User1: dog from A
(1, 2), -- User1: cat from A
(2, 1), -- User2: dog from A
(2, 2), -- User2: cat from A
(2, 3), -- User2: dog from B
(2, 4) -- User2: cat from B
如果您有像 user_events
这样的出席人数 table 并且领取礼物不是可选的,那么您就不需要 event_gift_claim
因为您可以从出席人数中得出所领取的内容 table.
例如,我们有一个系统可以让用户根据他们参加的活动索取 X 份礼物。
事件table:
| id | name |
----------------
| A | event A |
| B | event B |
礼物table:
| id | name | formula |
--------------------------
| 1 | dog | A*1 + B*2 |
| 2 | cat | (A|B)*3 |
在礼物table中我们有一些公式:
A*1 + B*2
- 参加活动A可获得1个玩具,参加活动B可再获得2个玩具。(A|B)*3
- 参加活动A或B的用户可以获得3个玩具。
公式在后端计算,但我想知道我们是否可以以某种方式在数据库中表示 event
和 gift
的关系?具体来说,我们希望:
SQL SELECT
event
基于gift
,反之亦然- 跟踪用户在每个
event
. 上声称
gift
基地的次数
非常感谢您
您需要的是一个桥接 table (associative entity),用于记录哪些用户访问过哪些事件。这看起来像下面这样:
User_Events
:
User_ID | Event_ID
------------------
1 | 1
1 | 2
2 | 2
请注意,每个值代表相关 table 中的一个外键 (id
)。
从这里,您可以应用基于 'events that the user has been to' 的逻辑,方法是查询如下内容:
SELECT E.*
FROM Users U
JOIN Events E
ON User_Events.User_ID = User_Events.Event_ID
您可以使用 many-to-many 关系 table 来表示礼物和事件之间的关系以及用户对礼物的要求:
CREATE TABLE event_gifts
(
id int PRIMARY KEY AUTO_INCREMENT,
event_id text REFERENCES event(id),
gift_id int REFERENCES gift(id)
);
CREATE TABLE event_gift_claim
(
id int PRIMARY KEY AUTO_INCREMENT,
user_id INT REFERENCES user(id),
event_gift_id INT REFERENCES event_gifts (id)
);
然后您可以跟踪事件和礼物之间的关系:
INSERT INTO event_gifts (event_id, gift_id)
VALUES
('A', 1),
('A', 2),
('B', 1),
('B', 2);
和select奖励特定礼物的事件:
SELECT event.*
FROM event
JOIN event_gifts
ON event_gifts.event_id = event.id
JOIN gift
ON gift.id = event_gifts.gift_id
WHERE gift.name = 'dog'
(或者反过来,来自活动的礼物)
您可以追踪谁声明了什么:
INSERT INTO event_gift_claim (user_id, event_gift_id) VALUES
(1, 1), -- User1: dog from A
(1, 2), -- User1: cat from A
(2, 1), -- User2: dog from A
(2, 2), -- User2: cat from A
(2, 3), -- User2: dog from B
(2, 4) -- User2: cat from B
如果您有像 user_events
这样的出席人数 table 并且领取礼物不是可选的,那么您就不需要 event_gift_claim
因为您可以从出席人数中得出所领取的内容 table.