2013-07-25 55 views
9

Tôi có một số dữ liệu cột động và số lượng dữ liệu cột có thể tăng/giảm bất cứ lúc nào. Vì vậy, tôi đang lập kế hoạch để lưu trữ chúng trong hàng khôn ngoan thay vì định dạng cột.Cách tốt nhất để lưu trữ dữ liệu cột dưới dạng hàng MS SQL

Tôi có bảng chính được đặt và cột chỉ ra loại dữ liệu mà cột đang sử dụng. Tôi vẽ bảng tổng thể dưới đây để bạn tham khảo

CID  Name   Type 
1  Speed   Double 
2  Input1  Bool 
3  Message  String 
....... 
....... 

Bây giờ tôi đã nghĩ đến hai cách để lưu trữ dữ liệu cột cách Đầu tiên năng động này là

CID  Data_bool  Data_String  Data_Double 
1  NULL   NULL    12 
2  True   NULL    NULL 
3  NULL   test    NULL 
1  NULL   NULL    5 
1  NULL   NULL    15 

cách thứ hai là phải có một cột VARCHAR khái quát hóa và lưu trữ từng giá trị dưới dạng chuỗi ở trên để nó trông giống như

CID  Datas 
1  12 
2  True 
3  test 
1  5 
1  15 

Nếu bạn nhìn vào quan điểm bình thường hóa cơ sở dữ liệu thì cách thứ hai dường như Trở nên tốt. Nhưng tôi nghĩ rằng nó có thể tạo ra vấn đề trong truy xuất dữ liệu. Bởi vì tôi muốn lọc dữ liệu như "Tốc độ> 10". Vì vậy, nếu tôi đi theo cách thứ hai (nơi tôi lưu trữ tất cả giá trị như chuỗi) tôi nghĩ rằng biểu thức sẽ mất nhiều thời gian hơn để đánh giá Và nếu tôi đi theo cách đầu tiên cho biểu thức thì trước tiên tôi cần phải xác định các cột mà tôi cần phải đánh giá biểu hiện. Ví dụ cho biểu thức Tốc độ> 10, đầu tiên tôi phải kiểm tra Tốc độ là loại dữ liệu (chuỗi, bool, v.v.) và sau đó thực hiện lại biểu thức của "data_double> 10"

Cả hai đều có nhược điểm riêng. Ai đó có thể chỉ ra rằng cách nào sẽ cho tôi ít đau đầu hơn trong tương lai. Hãy nhớ rằng bảng này sẽ phát triển trong hàng triệu bản ghi ở giai đoạn sau.

Tôi đánh giá cao tầm nhìn và thời gian của bạn tại đây. cảm ơn bạn.

+0

Sau khi suy nghĩ tất cả các khả năng, tôi đã quyết định đi theo con đường đầu tiên của mình. tôi biết nó không chuẩn hóa nhưng tôi nghĩ nếu tôi đi bình thường thì hiệu suất sẽ là vấn đề lớn. Tôi ổn (với trái tim nặng) với không gian HD hơn là tối ưu hóa tất cả các truy vấn để có hiệu suất nhanh hơn. Bảng này là trọng tâm của tất cả các báo cáo được tính toán. – user867198

Trả lời

1

Một cách tiếp cận có thể là sử dụng một bảng cho mỗi loại dữ liệu mà bạn quan tâm. Mỗi bảng này sẽ chỉ có hai trường. PK kiểu int và cột kiểu tương ứng để lưu trữ dữ liệu. Trong bảng chủ, bạn chỉ có thể có một FK của kiểu int liên kết với một trong các bảng loại cụ thể và một trường khác của loại tinyint quyết định bảng con nào thuộc về FK.

Thạc sĩ Bảng

ID int PK

ValueID int Not Null

Loại tinyint Không Null

Bảng Child (s)

ID int PK

Chuỗi giá trị Không Null

ValueID là FK từ bảng con thành bảng chính. Các bảng con tương tự có thể được tạo cho các loại khác.

+0

bạn không nghĩ rằng điều này sẽ làm cho truy vấn khó khăn? Đầu tiên tôi sẽ cần phải tìm bàn nào để tham gia và sau đó áp dụng tham gia. Tôi nghĩ rằng SQL động cũng sẽ đi vào chơi ở đây. – user867198

+0

Bạn có thể tạo một khung nhìn duy nhất, 'LEFT JOIN' trên tất cả các bảng con của bạn với bảng chính. Điều này sẽ tạo một cột cho mỗi bảng con trong dạng xem, giống như cấu trúc bảng đầu tiên mà bạn đã đăng trong câu hỏi của mình. – dotNET

2

Tôi không chắc chắn cách bạn truy cập dữ liệu, có thể SQL_Variant có thể là tùy chọn cho bạn kết hợp với SQL_VARIANT_PROPERTY.

Declare @a table(id int, cont sql_variant) 
insert into @a select 1,'test' 
insert into @a select 1,Cast('20130101' as DateTime) 
insert into @a select 1,Cast('20130201' as Datetime) 
insert into @a select 1,Cast(1 as Bit) 
insert into @a select 1,Cast(0 as Bit) 
Select * from 
(
Select * from @a 
where SQL_VARIANT_PROPERTY(cont,'BaseType')='datetime' 
) x 
Where cont>Cast('20130101' as DateTime) 
+0

Tôi mới sử dụng loại SQL_Variant này. Có vẻ đầy hứa hẹn nhưng khi kích thước bảng của tôi lớn hơn, bạn có nghĩ "SQL_VARIANT_PROPERTY (tiếp theo, 'BaseType') = 'datetime'" sẽ mất nhiều thời gian hơn? Bên cạnh đó nó thực sự trông mát mẻ – user867198

+0

A không thể đưa ra một câu trả lời chắc chắn về hiệu suất.Vì '(sql_variant_property ([cont], 'BaseType'))' không xác định, bạn không thể tạo một chỉ mục trên một colum được tính toán, vì vậy tôi mong đợi các vấn đề hiệu suất với nhiều dữ liệu. Vì trong trường hợp của tôi, các hàng được lọc trước bởi các điều kiện khác và SQL_VARIANT_PROPERTY được sử dụng để giải quyết các ánh xạ trường mà tôi không có vấn đề về hiệu năng trong trường hợp sử dụng mmy. – bummi

0

Tôi biết điều này không trả lời cho câu hỏi của bạn về lựa chọn nào trong số hai lựa chọn này tốt hơn nhưng tôi hy vọng nó sẽ hữu ích.

Tôi sẽ không thực hiện bất kỳ tùy chọn nào trong số hai tùy chọn này. Tôi muốn thử xem liệu tôi có thể xếp các cột này vào các cột không (không hiếm khi có các bảng có 50 hoặc 100 và thậm chí nhiều cột hơn) và/hoặc các bảng khác nhau.

Tôi khuyên bạn nên cài đặt TFS hoặc Dynamics CRM và xem cách chúng lưu trữ dữ liệu. Họ đã xây dựng mã ứng dụng để có thể thêm/xóa các cột trong cơ sở dữ liệu và chúng có một bộ bảng theo dõi dữ liệu meta này.

Nếu có thực sự có nhiều giá trị khác nhau hơn tôi thử với các loại dữ liệu XML.

+0

bạn nói đúng. Nhưng vấn đề của tôi ở đây là tôi không biết có bao nhiêu cột dữ liệu tôi sẽ nhận được xung quanh. Tôi đang theo mô hình gia tăng và sau đó tôi không muốn tạo lại bảng một lần nữa và một lần nữa để chứa thêm cột. XML cũng là cách nhưng tôi sợ sau đó lấy/lọc dữ liệu sẽ là một vấn đề lớn – user867198

0

Tôi đã xem và làm việc với loại sự cố này trong một số trường hợp, đặc biệt là khi ứng dụng phải cho phép cấu hình người dùng của tên trường và kiểu dữ liệu.

Giải pháp trong những trường hợp này là các bảng giá trị khóa (ví dụ 2 cột) sử dụng các biến cho tất cả các khóa [rõ ràng] mà còn cho tất cả các giá trị.

Đây là một giải pháp rất mạnh mẽ mà tuân theo sự đơn giản của nó!

Mặc dù đây là tùy chọn đơn giản nhất và có thể mở rộng nhưng nó có thể không phải là trình diễn xuất sắc nhất. Có một bảng khóa-giá trị cho từng loại dữ liệu có thể giúp nhưng khó hơn một chút để lập trình. Ngoài ra, hãy bao gồm trường Loại và cột cho từng loại dữ liệu trong cùng một bảng (nhưng không phải là mục ưa thích của tôi vì điều này làm lãng phí dung lượng).

Các ứng dụng dựa trên cơ sở dữ liệu tôi đã làm việc, sử dụng phương pháp tiếp cận giá trị varchar, được thực hiện mà không có sự chậm đáng chú ý; tuy nhiên, chúng thực sự chỉ hoạt động bằng cách sử dụng tra cứu dựa trên khóa đơn giản. Tình huống của bạn có thể khác nhau, đặc biệt nếu bạn thực hiện các truy vấn phức tạp hơn trên dữ liệu của mình. Nói rõ ràng, nhưng, việc áp dụng các khóa chính cho các trường Key sẽ cải thiện tốc độ tra cứu.

Ghi chú thêm:

Xin lỗi cho tái chế những gì tôi đã đọc trên các diễn đàn khác nhau nhưng tôi đã không sử dụng loại biến thể trong cơ sở dữ liệu của riêng tôi. Tôi đã đọc rằng:

1) Trong SQL Server 2005 trở đi, sử dụng một loại biến thể thay vì một loại varchar - trong trường hợp này, đối với cột Value - sẽ cho kết quả trong hoạt động nhanh hơn,

2) họ sẽ không bao không hoạt động với LIKE trong mệnh đề WHERE,

3) Nhà cung cấp OLE DB và ODBC tự động chuyển đổi các biến thể thành nvarchar (4000).

+0

Điều gì về việc kết hợp cách thứ nhất và thứ hai của tôi. Theo đề cập của "dotNET" dưới đây, tôi đã phân vùng bảng cách đầu tiên của tôi thành 3 bảng phụ (mỗi loại khác nhau) và lưu trữ giá trị trong 2 cột là ID và giá trị. Và còn lại tham gia tất cả các bảng mà sẽ cho tôi kết quả như cách đầu tiên của tôi. Tôi nghĩ nó có vẻ tốt – user867198

+0

Cách tiếp cận kết hợp, bao gồm ý tưởng xem LEFT JOIN của @ dotNET, nên phù hợp với nhu cầu của bạn tốt; Tôi sẽ đi với điều này. Nếu không thử nghiệm nó, tôi hy vọng hiệu suất sẽ không có vấn đề gì với tất cả các bộ dữ liệu khổng lồ. –

Các vấn đề liên quan