2017-04-01 58 views
0

我正在爲一款RPG遊戲開發團隊建設工具;我使用MySQL作爲我的數據庫,而InnoDB作爲存儲引擎。如何在一側實施有限數量關係的多對多關係? (MySQL)

在遊戲中,怪物擁有5個技能插槽,您可以通過物品添加技能,並且他們保存的順序非常重要(如果新技能添加時沒有空閒插槽,最舊技能會被覆蓋) - 當前,我有monsters表設置像這樣:

monster_id int not null, 
species_id int not null, 
user_id int not null, 
skill1_id int, # (fkey to skills.skill_id) 
skill2_id int, # (fkey to skills.skill_id) 
skill3_id int, # (fkey to skills.skill_id) 
skill4_id int, # (fkey to skills.skill_id) 
skill5_id int, # (fkey to skills.skill_id) 
# other irrelevant columns... 

這樣可以使技能,以便和防止怪物從具有比允許的最大更多的技能。然而,這似乎不是一個好的解決方案 - 這種設置不允許我快速查詢「選擇所有在任何插槽中都具有X技能的怪物」。我可以查詢所有5個插槽,但這看起來相當低效,因爲它依賴於一堆鏈接連接(它也不能很好地與我正在使用的ORM配合使用,儘管我可以寫下我自己的查詢它真的需要它)。

如果我使用標準化結合表monsters_skills像這樣這種關係:

monster_id int not null, 
skill_id int not null, 
slot_num int not null, 
primary key (monster_id, slot_num) # enforce one skill per-slot 

它將使查詢更容易「在任何插槽X技能所有怪物」 ......但數據庫不會強制實現每個怪獸的最大技能數量 - 據我所知,MySQL沒有正確支持CHECK約束,否則這在很大程度上解決了這個問題。我可以在我的實際應用程序代碼中執行檢查,但我非常希望數據庫在所有可能的情況下處理數據完整性。

我應該堅持使用我當前的解決方案(怪獸表中的編號插槽),還是有更好的方法在MySQL中實現這一點(通過表結構,觸發器等)?

+1

目前的解決方案並不是很好,但你可以很容易地用'where 1234 in(skill1_id,skill2_id,...,skill5_id)來查詢'使用'1234'作爲skill_id的示例 –

+1

您可以使用觸發器來執行最大的slot_num。 – reaanb

回答

0

瞭解如何在SQL中使用觸發器。您需要讓DBMS強制執行完整性。總的來說,你總是不能擺脫總是使用不正確的設計和MySQL的SQL子集的聲明性約束收集的子集。 (你現在的設計不僅限於有效狀態,是嗎?)(你實際上沒有說出一行是如何映射到一個有序的技能列表的,用於查詢,以及一個有序的技能列表如何映射到一行)