2016-11-11 56 views
1

我正在爲我的遊戲製作一個數據庫,我需要存儲很多c風格的結構。爲T-SQL創建一個結構類型作爲列值?

struct stats{ 
    int strength, stamina, agility, intelligence, etc..; 
} 

我一直在尋找如何在T-SQL創建用戶定義的數據類型和MSDN明確表示,用戶定義的數據類型不能用作列類型:

A user-defined table type cannot be used as a column in a table or a field in a structured user-defined type.

有沒有解決方法,或者其他方式來創建一個基於結構的系統?我也需要一個技能結構,並且我有大約120+技能需要存儲在我的玩家表下。我所需的表會是這個樣子:

CREATE TABLE [dbo].[Player](
    player_name nvarchar (20), 
    gold int, 
    player_stats stats,     // array of 4 ints 
    player_skills skills,    // array of 120+ tinyints 
    player_location location,   // array of 3 floats (x,y,z) 
    player_customization customization, // array of 20+ tinyints 
    player_equipment equipment,   // array of 8 ints 
    etc....) 

是否有這樣做的一個簡單的方法還是我只需要添加所有這些作爲單獨的列類型?謝謝您的幫助。

+1

這是不是很規範化。你應該考慮把它分成不同的列。 –

+0

通常,您需要爲每個結構定義一個表,其中的列與結構中的每個字段對齊。 –

回答

1

這是你的表:

CREATE TABLE [dbo].[Players](
    player_name nvarchar (20), 
    gold int, 
    player_stats stats,     // array of 4 ints 
    player_skills skills,    // array of 120+ tinyints 
    player_location location,   // array of 3 floats (x,y,z) 
    player_customization customization, // array of 20+ tinyints 
    player_equipment equipment,   // array of 8 ints 
    etc.... 
) 

這表明,你應該有其他幾個表和列:

  • Player_SkillsSkills:每個球員,每個技能一行,也許技能級別列也是如此。
  • Location:每個位置一行,包含有關位置的信息。 LocationId將在Players表中。
  • Player_EquipmentEquipment:每個玩家和每個裝備一行。

我不知道player_statsplayer_customization是什麼。也許他們只是適合Players;也許他們應該是他們自己的桌子。

您正在考慮關係數據庫的編程結構,如「結構」不合適。

1

幾個除了戈登的其他建議:

  1. 作出的Player表不是一個VARCHAR主鍵。 A VARCHAR列不是一個好主鍵;一個更好的密鑰類型將是INT(或者如果期望超過2^31-1個玩家,則爲BIGINT;))。與使用字符串的鍵查找相比,使用整數進行鍵查找更快。還要考慮你必須在其他表格(細節表)中通過主鍵來引用玩家。

    最簡單的方法是讓SQL Server爲您創建一個整數鍵。您可以通過將IDENTITY列添加到表中,並將該列作爲主鍵來完成此操作。在這種情況下,對於每個插入到玩家表中的密鑰將被分配給玩家。您必須在player_name列的表格中添加INDEX,不過在某些時候您必須按名稱查找球員。

    例如:

    CREATE TABLE player(
        player_id INT IDENTITY(1,1) NOT NULL, 
        player_name NVARCHAR(128), 
        -- ... other columns 
        CONSTRAINT PK_player PRIMARY KEY CLUSTERED (player_id) 
    ); 
    
    CREATE INDEX 
        IX_player_name 
    ON 
        player(player_name); 
    
  2. 正如戈登已經指出的,結構的結構或陣列不能被存儲在表中作爲這樣。設計表格的好方法是爲每個玩家分配一組邏輯數據,創建一個鏈接到玩家表格的(詳細)表格。關係數據庫對於列數儘可能少的表格更容易。

    的一組信息(結構),不象player_location你可能會說,直接在播放器表存儲該信息(列XYZ)改變。更好的做法是將這些邏輯分組的信息集合在一個單獨的表中player_location。然後,玩家表格和位置表格之間會有1:1的關係。的信息,如player_equipment

    CREATE TABLE player_location(
        player_id INT NOT NULL, 
        x FLOAT NOT NULL, 
        y FLOAT NOT NULL, 
        z FLOAT NOT NULL, 
        CONSTRAINT PK_player_location PRIMARY KEY CLUSTERED (player_id) 
        CONSTRAINT FK_player_location FOREIGN KEY(player_id) REFERENCES player(player_id) 
    ); 
    

    其他團體將繼續增長,因爲我認爲球員會拿起設備,因爲他們通過玩遊戲。另一方面是隨着遊戲的增長,你可能會增加新的裝備(通過mods說)。假設你現在有100種類型的裝備,但是在你的擴展中你會增加100種新裝備。假設你採取以前的建議,創建一個有100列的表格,然後當你釋放MOD時,你將不得不添加100個新列。

    在表中有很多列本身就是一個壞主意,再加上當你釋放mod時你將不得不改變設備表。這種思維方式的另一個方面是,你將不得不存儲100個(或者在mod之後200個)數據列,這些列不一定包含任何相關信息。玩家可能只有20個設備,而你將不得不存儲100(200)列。這將浪費磁盤/內存空間。

    一個更好的建模方法是定義一個定義表,該表定義了設備和玩家設備表,該表存儲玩家持有的設備。例如:

    CREATE TABLE equipment(
        equipment_id INT NOT NULL, 
        equipment_name NVARCHAR(128) NOT NULL, 
        -- ... 
        CONSTRAINT PK_equipment PRIMARY KEY CLUSTERED (equipment_id) 
    ); 
    
    CREATE TABLE player_equipment(
        player_id INT NOT NULL, 
        equipment_id INT NOT NULL, 
        amount INT NOT NULL, 
        CONSTRAINT PK_player_equipment PRIMARY KEY CLUSTERED (player_id,equipment_id), 
        CONSTRAINT FK_player_equipment FOREIGN KEY(player_id) REFERENCES player(player_id), 
        CONSTRAINT FK_equipment FOREIGN KEY(equipment_id) REFERENCES equipment(equipment_id) 
    ); 
    

    當你發佈一個新的MOD,你會在equipment表中添加新的設備,當玩家拿起新的廠房設備將添加一行到player_equipment表通過其ID引用設備。

無論如何,這些是你深入研究的一些想法。一個好的數據庫模型將允許您以更簡單的方式(較不復雜)執行寫查詢,並允許數據庫消耗更少的內存和磁盤空間。