2012-11-06 83 views
0

我的问题比例子更普遍,但我认为说明这个想法的唯一方法是使用样例。MySQL - 多个唯一/约束到数量

比方说,我想为聊天应用程序创建一个数据库。将会有一个主题列表。任何时候任何“房间”4个用户。

说有一个话题叫做“贝多芬”。如果用户选择该主题,则会提取或创建一个房间。一旦有4个用户加入该房间,就会创建另一个房间实例(同一主题),在另一个实例创建之前,这将占用最多4个用户。如果来自第一个房间实例的用户离开,则该插槽已打开,因此加入主题的第九个用户将被发送到第一个房间实例。

管理这个最好的方法是什么?我有2个想法:

  1. “主题” 表:ID,标签
  2. “房间” 表:ID,topicId
  3. “人口” 表:roomId,用户id

当用户选择/加入主题,如SELECT COUNT(userId) FROM Population WHERE topicId = <id> ... if count> 4,创建一个新房间,插入它并返回插入ID。当用户离开房间时,人口中的那一行被删除。

或者......

  1. “主题” 表:ID,标签
  2. “房间” 表:ID,topicId,用户1,用户2,用户3,USER4。当用户加入

然后,像SELECT id FROM Rooms WHERE ISNULL(user1) OR ISNULL(user2) OR ISNULL(user3) OR ISNULL(user4) LIMIT 1

如果没有匹配的行,插入一个新的房间,并返回插入的ID。当用户离开房间时,该列被设置为NULL。

TYIA。

回答

0

我使用了你的第一个模式。

获取的非全室的列表:

SELECT room.id 
FROM  topic 
INNER JOIN room  ON room.topic_id = topic.id 
INNER JOIN population ON population.room_id = room.id 
WHERE topic.label = 'purcell' 
GROUP BY room.id 
HAVING COUNT(*) < 4 

获得第一个非满房间ID或NULL,如果没有这样的房间里发现:

SELECT MIN(room_id) 
FROM (
    SELECT room.id AS room_id 
    FROM  topic 
    INNER JOIN room  ON room.topic_id = topic.id 
    INNER JOIN population ON population.room_id = room.id 
    WHERE topic.label = 'purcell' 
    GROUP BY room.id 
    HAVING COUNT(*) < 4 
) AS non_full_rooms 
+0

很好,谢谢。一般而言,你会说第一种方法是最优的?不一定与我明确列出的两种方法相比,但总的来说 - 这是你如何处理任务?再次感谢 – momo

+0

正如你所看到的,我只是将第一个选择包装到另一个中,所以如果你想以编程方式选择一个房间,第一个给你一个列表,第二个总是给你一行(id或null),所以我不会认为两者之间存在可测量的差异:) – biziclop