2012-11-06 109 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