Làm thế nào để lưu trữ dữ liệu không có lược đồ một cách hiệu quả trong cơ sở dữ liệu quan hệ?


7

Tôi đang cố gắng để có được sự cân bằng tốt về khả năng tìm kiếm và tốc độ. Tôi đang thử nghiệm các phương pháp khác nhau.

Tùy chọn 1: Tuần tự hóa mảng dưới dạng mảng tuần tự JSON / PHP và lưu trữ nó trong cột 'meta'.

   id  |  name   | meta  
1       Bob       {"city":"GoTown","birthdate":"1980\/8\/14","cat":"Felix"}
2       Alice     {"city":"Streamville","birthdate":"1986\/6\/6","dog":"Rex"}

Tùy chọn 2: Lưu trữ các khóa và giá trị với nhau trong một ngăn xếp.

user_id  |    key   |   value   
1         name       Bob
1         city       GoTown
1         birthdate  1980/8/14
1         cat        Felix
2         name       Alice
2         city       Streamville
2         birthdate  1986/6/6
2         dog        Rex

Tùy chọn 3: 3 bảng: quyền, khóa, giá trị. Lưu trữ mỗi tên khóa chỉ một lần.

user_id  |   name   
1         Bob
2         Alice

key_id   |   keyname   
1         city
2         birthdate
3         cat
4         dog

user_id   |   key_id   |   value
1          1            GoTown
1          2            1980/8/14
1          3            Felix
2          1            Streamville
2          2            1986/6/6
2          4            Rex

Có bất kỳ cạm bẫy với việc sử dụng bất kỳ chiến lược trong số này? Tôi muốn loại bỏ một số trong số họ nếu họ có những nhược điểm không thể vượt qua.

EDIT: Đã thêm một số dữ liệu để biểu thị dữ liệu không có lược đồ

Câu trả lời:


3

Một số vấn đề thực sự khó chịu sẽ xảy ra với các bảng này (ý tưởng)

  1. Dự phòng dữ liệu (dữ liệu trùng lặp) những gì bạn cần giữ đồng bộ hóa (và bạn có kiểm tra điều này không vì MySQL không có chức năng JSON để ghi lại?)

  2. Bạn không thể buộc các giá trị chính xác trên cơ sở dữ liệu (nói lời tạm biệt với tính toàn vẹn dữ liệu và xin chào dữ liệu rác thải) ví dụ ngày sinh khóa có thể có giá trị "xin chào"

Và bạn cần một số loại truy vấn trục để tìm nạp khóa / giá trị

Nếu bạn thực sự cần lưu trữ giá trị khóa động (EAV), có một số tùy chọn khác:


3

Đưa ra các yêu cầu của bạn (MySQL và "lược đồ không"), tôi nghĩ rằng có thể đáng để xem xét Tùy chọn 1 với một bước ngoặt. Hãy xem xét XML thay vì JSON.

Tại sao? Bởi vì MySql không cung cấp cho bạn một cách dễ dàng để xử lý JSON, nhưng nó thực hiện với xml.

Xem xét điều này:

id  |  name   | meta  
1      Bob      <city>GoTown</city><birthdate>1980-08-14&</birthdate>
2      Alice    <city>Streamville</city><birthdate>1986-06-06<birthdate>

Bây giờ bạn có thể thực hiện truy vấn sql bằng biểu thức xpath trên nội dung của trường meta. Thích như vậy:

SELECT name, extractValue( meta, '//birthdate' ) as birthdate
from tbl

Bạn thậm chí có thể thực hiện các lựa chọn dựa trên thành phố (tất nhiên sẽ RẤT kém hiệu quả vì chúng sẽ phải phân tích nội dung của các trường khớp với mệnh đề where, nhưng:

SELECT name<BR>
from tbl<br>
where id < 100
having extractValue( meta, '//city' ) = 'Streamille'

Bạn thậm chí có thể sử dụng UpdateXML (một chức năng khác của MySQL) để thay đổi nội dung của lĩnh vực của bạn trong MySQL.

Trong khi tôi biết phản hồi của mình là muộn, tôi hy vọng ai đó thấy điều này hữu ích / thú vị. :)


3

Từ dữ liệu mẫu của bạn, tôi thực sự thấy một lược đồ cho bảng

UserID | UserName | City | Birthdate

Nếu bạn đang sử dụng cơ sở dữ liệu quan hệ với việc lập chỉ mục đúng thì việc tìm kiếm trên đó sẽ rất nhanh. Nếu một số giá trị có thể là null thì cho phép các cột nullable.

Một kho lưu trữ giá trị quan trọng là rất tốt trong các tình huống nhưng có thể trở nên rất cồng kềnh khi xác thực dữ liệu. Nếu bạn đang sử dụng một sản phẩm cơ sở dữ liệu quan hệ, hãy đặt nó hoạt động và để nó thực hiện xác nhận ở phía đầu vào với các cột được nhập đúng.

Nếu bạn thực sự muốn sử dụng kho lưu trữ giá trị khóa, một sản phẩm NoQuery được tối ưu hóa cho chúng có lẽ là cách tốt hơn để sử dụng.


2

Cộng đồng wiki trả lời :

Postgres có nhiều tính năng NoQuery hơn MySQL. Việc triển khai JSON hiệu quả hơn nhiều (bạn có thể lập chỉ mục các tài liệu JSON) và nó có kho lưu trữ khóa / giá trị rất hiệu quả (cũng có thể lập chỉ mục). Postgres có lẽ là "cơ sở dữ liệu quan hệ NoQuery" tiên tiến nhất.


1

Nếu bạn có thể cần phải tìm kiếm tất cả các khách hàng có sinh nhật trong khoảng thời gian từ 08/10 đến 17/8, thì tùy chọn 1 không phù hợp.

Tùy chọn 2 và 3 tương tự nhau. Cá nhân tôi thích tùy chọn 3 vì tôi thích tìm kiếm hoặc nhóm theo mã số nguyên hơn là theo văn bản.

Và nhân tiện. Tôi khuyên nên lưu trữ tháng và ngày là 2 số. Sau đó, bạn có thể sắp xếp chúng thành các chuỗi và nó vẫn sẽ chính xác: 1970/10/10 sẽ là sau 1970/08/08, nhưng sẽ là trước 1970/8/8.


Mẹo hay với ngày, NẾU bạn buộc phải lưu một ngày có thể đọc được của con người - thông thường sẽ tốt hơn nếu sử dụng unixtime trong DB như được đề cập bởi @capnhector.
techturbulence

1

Nếu bạn không ổn định khi sử dụng MySQL, bạn có thể coi DB2 là một tùy chọn. Nó có hỗ trợ riêng cho dữ liệu JSON, cho phép bạn truy vấn và thao tác các đoạn JSON dễ dàng ( http://publib.boulder.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.swg.im.dbclient.json .doc / doc / c0061316.html ).

Một cách khác là XML. Một lần nữa, DB2 có hỗ trợ riêng cho nó, bao gồm lập chỉ mục các biểu thức XPath để tìm kiếm nhanh. ( http://publib.boulder.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.db2.luw.xml.doc/doc/c0022308.html )

DB2 Express-C là phiên bản miễn phí, không hạn chế sử dụng sản xuất hoặc kích thước cơ sở dữ liệu.



-1

Bạn đã xem xét NoQuery chưa?

Bởi vì tôi làm việc cho một nhà cung cấp NoQuery, tôi là một phần nhưng tôi đã cố gắng đưa định nghĩa vấn đề của bạn và xem nó từ lăng kính về công nghệ nào là tốt nhất. Mô tả này là lý tưởng cho NoQuery vì nó hỗ trợ dữ liệu phi cấu trúc và tất cả các tùy chọn bạn chia sẻ đều có thể thực hiện được trong NoQuery. Theo tôi, tùy chọn 3 khá hấp dẫn vì trong một khoảng thời gian tối thiểu bạn có thể tạo các bảng đó và được thực hiện với nó. Và nếu bạn cần thêm các cột bổ sung, nó không quan trọng và bạn có thể giữ các phiên bản dữ liệu của mình. Và hầu hết các DB của NoQuery đều hỗ trợ truy vấn bằng nhiều cách khác nhau và hầu hết các cách này nằm trong mô hình của bạn.

Hầu hết các DB NoQuery như FatDB và RavenDB đều nghĩ đến và sẽ hoạt động tốt cho việc này cho không gian Windows. MongoDB, vv, cho những người khác.


1
Umm, OP đã tìm kiếm các mẹo về cách triển khai các tính năng như "NoQuery" trong cơ sở dữ liệu quan hệ, tức là không phải là cơ sở dữ liệu NoQuery.
Colin 't Hart
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.