Tôi cần lưu trữ dữ liệu liên quan đến "mục", nơi sẽ có nhiều loại mục khác nhau, tất cả đều có thuộc tính phổ biến và sau đó mỗi loại có thuộc tính bổ sung của riêng nó. Tôi hy vọng đây là một yêu cầu chung; giải pháp thực hành tốt nhất là gì? Chúng tôi đang sử dụng SQL Server.Các mục và các mục chuyên biệt: Nhiều bảng có các cột trùng lặp, bảng chính và bảng chi tiết, hoặc ...?
Hãy sử dụng làm-up dụ:
xe có
- Giá
- Hãy
- Mẫu
- Chủ
(Trong dữ liệu thực tế của chúng tôi , sẽ có 10-15 cột chung)
xe là một xe cộng:.
- Style (sedan, thể thao, vv)
- Màu
- EngineSize
Thuyền là Phương tiện cộng thêm:
- Displacement
- PortOfOrigin
... vv. đối với một số loại sự vật. Trong dữ liệu thực của chúng tôi, mỗi loại chuyên biệt thường sẽ thêm 2-5 cột; sẽ có 5 loại để bắt đầu. Chúng tôi sẽ thêm các loại theo thời gian, nhưng có lẽ chỉ có tổng cộng 3 hoặc 4 tổng số (nếu có). Thêm loại yêu cầu phát triển, do đó, nó không giống như "thẻ" có thể được thêm vào bởi người dùng cuối. Chúng tôi giả định việc thêm một loại sẽ yêu cầu thay đổi đối với các tầng DB và tầng khách hàng, và có thể là tầng giữa. Điều đó hoàn toàn ổn.
Chúng tôi sẽ thực hiện nhiều truy vấn trên tất cả các mục (xe, trong ví dụ ở trên); chúng tôi chỉ lo lắng về các chi tiết của một loại mặt hàng cụ thể (Ô tô, Thuyền) hiếm khi.
tôi thấy bốn cách để lưu trữ dữ liệu này:
- bảng riêng biệt cho Xe hơi, Thuyền, vv với các cột trùng lặp.
- Một bảng có dữ liệu
Vehicle
, một bảng cho dữ liệuCar
bổ sung và bảng cho dữ liệu bổ sungBoat
. - Một bảng mục, một bảng thuộc tính mục riêng biệt với một hàng cho mỗi thuộc tính bổ sung. Ví dụ: một lược đồ mềm cho các chi tiết.
- Một bảng có các cột chung được cung cấp chỉ có ý nghĩa bởi mã không phải DB.
Nhìn vào mỗi:
bảng riêng biệt cho Xe hơi, Thuyền, vv với các cột trùng lặp. Ví dụ, khoảng:
CREATE TABLE [Cars] ( [Id] IDENTITY PRIMARY KEY, [Price] DECIMAL (19, 4), [Make] NVARCHAR(200), [Model] NVARCHAR(200), [Owner] INT, [Id] INT PRIMARY KEY, [Style] NVARCHAR(200), [Color] NVARCHAR(200), [EngineSize] DECIMAL(19, 2) ) CREATE TABLE [Boats] ( [Id] IDENTITY PRIMARY KEY, [Price] DECIMAL (19, 4), [Make] NVARCHAR(200), [Model] NVARCHAR(200), [Owner] INT, [Id] INT PRIMARY KEY, [Displacement] DECIMAL(19, 4), [PortOfOrigin] NVARCHAR(200) )
đủ đơn giản, Ô tô đi vào
Cars
và Thuyền đi trongBoats
. Nếu chúng ta thêm nhiều loại xe, chúng ta thêm một cái bàn. Nếu chúng ta thêm một cột chung khác, chúng ta phải quay trở lại và thêm nó vào tất cả các bảng xe. Báo cáo chống lại xe nói chung có thể được thực hiện đối với một cái nhìn công đoàn của tất cả các bảng (cẩn thận về cộtId
).Một bảng có dữ liệu
Vehicle
, bảng cho dữ liệuCar
bổ sung và bảng cho dữ liệu bổ sungBoat
. Ví dụ, khoảng:CREATE TABLE [Vehicles] ( [Id] IDENTITY PRIMARY KEY, [Price] DECIMAL (19, 4), [Make] NVARCHAR(200), [Model] NVARCHAR(200), [Owner] INT, [Type] INT -- A type ID, e.g. "Car" vs. "Boat" ) CREATE TABLE [Cars] ( [Id] INT PRIMARY KEY, [Style] NVARCHAR(200), [Color] NVARCHAR(200), [EngineSize] DECIMAL(19, 2) ) CREATE TABLE [Boats] ( [Id] INT PRIMARY KEY, [Displacement] DECIMAL(19, 4), [PortOfOrigin] NVARCHAR(200) )
Vì vậy, mỗi xe sẽ có một hàng trong
Vehicles
và một hàng liên kết trongCars
. Mỗi Thuyền sẽ có một hàng trong sốVehicles
và một hàng được liên kết trongBoats
. Nếu chúng ta thêm nhiều loại xe, chúng ta thêm một cái bàn. Báo cáo đối với xe nói chung có thể được thực hiện chỉ với bảngVehicle
. Khi truy xuất chi tiết về một số cụ thểCar
hoặcBoat
, chúng tôi sử dụng kết nối.Một bảng mục, một bảng thuộc tính mục riêng biệt với một hàng cho mỗi thuộc tính bổ sung. Ví dụ: một lược đồ mềm cho các chi tiết. Ví dụ, khoảng:
CREATE TABLE [Vehicles] ( [Id] IDENTITY PRIMARY KEY, [Price] DECIMAL (19, 4), [Make] NVARCHAR(200), [Model] NVARCHAR(200), [Owner] INT, [Type] INT ) CREATE TABLE [VehicleDetails] ( [VehicleId] INT, [Name] NVARCHAR(200), [Value] NVARCHAR(MAX) )
Vì vậy, mỗi xe được một hàng trong
Vehicles
và ba hàng trongVehicleDetails
(một cho mỗi "Style", "Color", và "EngineSize"). Báo cáo được thực hiện phần lớn trên bảngVehicle
. Báo cáo về chi tiết bắt đầu nhận được nhanh chóng lộn xộn. Các lược đồ mềm có vị trí của chúng, chủ yếu là xung quanh dữ liệu do người dùng định nghĩa, nhưng tôi cho rằng đây không phải là lựa chọn tốt ở đây.Một bảng với các cột chung cho ý nghĩa chỉ cho phép code-DB phi:
CREATE TABLE [Vehicles] ( [Id] IDENTITY PRIMARY KEY, [Price] DECIMAL (19, 4), [Make] NVARCHAR(200), [Model] NVARCHAR(200), [Owner] INT, [Type] INT, [Detail01] NVARCHAR(MAX), [Detail02] NVARCHAR(MAX), [Detail03] NVARCHAR(MAX), [Detail04] NVARCHAR(MAX), [Detail05] NVARCHAR(MAX), [Detail06] NVARCHAR(MAX), [Detail07] NVARCHAR(MAX), [Detail08] NVARCHAR(MAX), [Detail09] NVARCHAR(MAX), [Detail10] NVARCHAR(MAX) )
dữ liệu Vì vậy, xe sẽ gán Style
Detail01
, màu đểDetail02
và EngineSize đểDetail03
; cho Thuyền, chúng tôi sẽ đặt Displacement vàoDetail01
và PortOfOrigin trongDetail02
. Tương tự, có thể có một vị trí cho điều này với các lược đồ được xác định bởi người dùng cuối, nhưng tôi đoán đây không phải là câu trả lời hay khi bạn có thể kiểm soát cấu trúc DB.
Cơ sở dữ liệu quan hệ có được yêu cầu nghiêm ngặt không? Dường như việc sử dụng cơ sở dữ liệu tài liệu cho mô hình này sẽ phù hợp hơn. – Oded
@Oded: Câu hỏi hay. Trong trường hợp này, có, nó phải được lưu trữ trong RDBMS, ít nhất là bây giờ. Nếu chúng ta có đủ các loại yêu cầu này, có lẽ chúng ta sẽ tăng thêm RDBMS bằng một cơ sở dữ liệu tài liệu. –
"chúng tôi sẽ thêm nhiều loại theo thời gian" - cho biết tùy chọn 2 đối với tôi. Một lược đồ mềm (mô hình EAV) là một khởi đầu không phải là các cột chung một. – Oded