Tôi sẽ không đồng ý với tất cả mọi người và nói rằng cách tiếp cận quan hệ là hợp lý ở đây. Điều thú vị ở đây là các mặt hàng có thể có nhiều vai trò. Vấn đề chính là việc ánh xạ giữa bố cục quan hệ này và bố cục OO trong mã sẽ không cảm nhận được tự nhiên, nhưng tôi nghĩ về phía cơ sở dữ liệu, nhiều vai trò có thể được thể hiện rõ ràng (không có mã hóa hoặc dự phòng lạ, chỉ cần tham gia) .
Điều đầu tiên để quyết định là bao nhiêu dữ liệu là mục cụ thể và bao nhiêu được chia sẻ bởi tất cả các mục của một loại nhất định.
Đây là những gì tôi sẽ làm nếu tất cả dữ liệu là mục cụ thể:
// ITEMS table: attributes common to all items
item_id | name | owner | location | sprite_id | ...
1 | Light Saber | 14 (Tchalvek) | 381 (Tchalvek house) | 5663 | ...
// WEAPONS table: attributes for items that are weapons
item_id | damage | damage_type | durability | ...
1 | 5 | sharp | 13 | ...
// LIGHTING table: attributes for items that serve as lights
item_id | radius | brightness | duration | ...
1 | 3 meters | 50 | 8 hours | ...
Trong thiết kế này, mọi mục đều nằm trong bảng Mục, cùng với các thuộc tính mà tất cả (hoặc hầu hết) các mục có. Mỗi vai trò bổ sung mà một vật phẩm có thể đóng là một bảng riêng biệt.
Nếu bạn muốn sử dụng nó làm vũ khí, bạn sẽ tìm kiếm nó trong bảng Vũ khí. Nếu nó ở đó, thì nó có thể sử dụng như một vũ khí. Nếu nó không ở đó, thì nó không thể được sử dụng làm vũ khí. Sự tồn tại của hồ sơ cho bạn biết đó có phải là vũ khí hay không. Và nếu nó ở đó, tất cả các thuộc tính dành riêng cho vũ khí của nó được lưu trữ ở đó. Vì các thuộc tính đó được lưu trữ trực tiếp thay vì ở dạng được mã hóa, bạn sẽ có thể thực hiện các truy vấn / bộ lọc với chúng. (Ví dụ: đối với trang số liệu của trò chơi của bạn, bạn có thể muốn tổng hợp người chơi theo loại sát thương vũ khí và bạn có thể làm điều đó với một số phép nối và damage_type theo nhóm.)
Một vật phẩm có thể có nhiều vai trò và tồn tại trong nhiều bảng cụ thể theo vai trò (trong ví dụ này, cả vũ khí và ánh sáng).
Nếu nó chỉ là một kiểu boolean như "cái này có thể giữ được", tôi sẽ đặt nó vào bảng Vật phẩm. Nó có thể đáng lưu vào bộ nhớ cache "đây có phải là vũ khí" không, v.v. để bạn không phải thực hiện tra cứu Vũ khí và các bảng vai trò khác. Tuy nhiên, nó bổ sung tính dự phòng nên bạn phải cẩn thận để giữ cho nó đồng bộ.
Khuyến nghị của Ari về việc có một bảng bổ sung cho mỗi loại cũng có thể được sử dụng với phương pháp này nếu một số dữ liệu sẽ không thay đổi theo từng mục. Ví dụ: nếu sát thương vũ khí không thay đổi theo từng vật phẩm, nhưng vai trò vẫn thay đổi theo từng vật phẩm, bạn có thể tính các thuộc tính vũ khí được chia sẻ vào một bảng:
// WEAPONS table: attributes for items that are weapons
item_id | durability | weapon_type
1 | 13 | light_saber
// WEAPONTYPES table: attributes for classes of weapons
weapon_type_id | damage | damage_type
light_saber | 5 | energy
Một cách tiếp cận khác là nếu vai trò của các vật phẩm không thay đổi theo vật phẩm, mà chỉ theo loại vật phẩm. Trong trường hợp đó, bạn đặt item_type vào bảng Vật phẩm và có thể lưu trữ các thuộc tính như "nó có phải là vũ khí" và "có thể giữ được không" và "có phải là đèn" trong bảng ItemTypes không. Trong ví dụ này tôi cũng làm cho tên các mặt hàng không thay đổi theo từng mặt hàng:
// ITEMS table: attributes per item
item_id | item_type | owner | location
1 | light_saber | 14 (Tchalvek) | 381 (Tchalvek house)
// ITEMTYPES table: attributes shared by all items of a type
item_type | name | sprite_id | is_holdable | is_weapon | is_light
light_saber | Light Saber | 5663 | true | true | true
// WEAPONTYPES table: attributes for item types that are also weapons
item_type | damage | damage_type
light_saber | 5 | energy
Có khả năng các loại vật phẩm và vũ khí không thay đổi trong trò chơi, vì vậy bạn chỉ cần tải các bảng đó vào bộ nhớ một lần và tìm kiếm các thuộc tính đó trong bảng băm thay vì tham gia cơ sở dữ liệu.