对接会网络活动参与者的关系数据库模式和查询

Relational database schema and queries for matchmaking networking event attendees

我正在为社交活动的参加者开发一个应用程序,并且对关系数据库没有太多经验。每一轮(10 分钟)与会者都会结对见面并相互了解。该应用程序不应在后续轮次中将与会者与同一个人匹配。

这是我最初设计的模式:

CREATE TABLE IF NOT EXISTS attendees (
    id SERIAL,
    name varchar NOT NULL,

    CONSTRAINT pk_attendees_id PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS matches (
    id SERIAL,
    attendee_id integer NOT NULL,
    partner_id integer NOT NULL,
    has_met boolean DEFAULT false,

    CONSTRAINT pk_matches_id PRIMARY KEY (id),
    CONSTRAINT fk_attendee_id FOREIGN KEY (attendee_id) REFERENCES attendees(id),
    CONSTRAINT fk_partner_id FOREIGN KEY (partner_id) REFERENCES attendees(id)
);

示例数据:

INSERT INTO attendees (name) VALUES
('john'),
('leland'),
('becky'),
('jerome'),
('sarah'),
('ahmed'),
('mike'),
('greg'),
('jessica'),
('latoya'),
('emily'),
('jake');

INSERT INTO matches (attendee_id, partner_id, has_met) VALUES
(1, 4, true),
(4, 1, true),
(3, 2, true),
(2, 3, true),
(5, 6, true),
(6, 5, true),
(7, 9, true),
(9, 7, true),
(5, 1, true),
(1, 5, true),
(7, 3, true),
(3, 7, true),
(2, 6, true),
(6, 2, true),
(8, 3, true),
(3, 8, true);

以下查询 return 在不允许任何已经匹配的与会者在这一轮中再次配对的情况下可以进行的所有唯一匹配:

SELECT a.id, a.name, b.id, b.name
FROM attendees a
CROSS JOIN attendees b
WHERE a.id < b.id
AND b.id NOT IN (
    SELECT m.partner_id
    FROM matches m
    WHERE a.id = m.attendee_id
)
ORDER BY a.id;

在我的应用程序中,我能够获取上述查询的结果和 select 每个与会者的配对。是否可以将查询修改为每个与会者仅return一个结果?

上述方法很可能是错误的,因为数据没有被归一化。我得出这个结论是否正确?

我已尝试重新设计架构以不重复数据:

CREATE TABLE IF NOT EXISTS attendees (
    id SERIAL,
    name varchar NOT NULL,

    CONSTRAINT pk_attendees_id PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS matches (
    id SERIAL,
    has_met boolean DEFAULT false,

    CONSTRAINT pk_matches_id PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS participants (
    id SERIAL,
    match_id integer NOT NULL,
    attendee_id integer NOT NULL,

    CONSTRAINT pk_participants_id PRIMARY KEY (id),
    CONSTRAINT fk_matches_match_id FOREIGN KEY (match_id) REFERENCES matches(id),
    CONSTRAINT fk_matches_attendee_id FOREIGN KEY (attendee_id) REFERENCES attendees(id)
);

示例数据:

INSERT INTO attendees (name) VALUES
('john'),
('leland'),
('becky'),
('jerome'),
('sarah'),
('ahmed'),
('mike'),
('greg'),
('jessica'),
('latoya'),
('emily'),
('jake');

INSERT INTO matches (has_met) VALUES
(true),
(true),
(true),
(true),
(true),
(true);

INSERT INTO participants (match_id, attendee_id) VALUES
(1, 1),
(1, 3),
(2, 4),
(2, 12),
(3, 5),
(3, 7),
(4, 9),
(4, 8),
(5, 11),
(5, 6),
(6, 2),
(6, 10);

上面的数据库模式是否设计正确?

如何查询 return 每一轮的可能配对,以免重复?是否可以让数据库识别每一轮的确切配对,或者这是必须在应用程序中完成的事情?

根据您的描述,您有两个实体:

  • attendees
  • matches

“与会者”实际上可能是参与者;我不确定。

然后你有一个连接点 table 将它们组合起来:

  • matchAttendees

每场比赛和每位与会者一行。

如果您想查看谁在之前的匹配中没有匹配到,您可以对这些 table 执行查询。