Cách lưu danh sách trong một cột của bảng cơ sở dữ liệu


114

Vì vậy, theo câu trả lời của Mehrdad cho một câu hỏi liên quan , tôi hiểu rằng cột bảng cơ sở dữ liệu "thích hợp" không lưu trữ danh sách. Thay vào đó, bạn nên tạo một bảng khác có hiệu quả chứa các phần tử của danh sách đã nói và sau đó liên kết đến nó trực tiếp hoặc thông qua một bảng nối. Tuy nhiên, loại danh sách tôi muốn tạo sẽ bao gồm các mục duy nhất (không giống như quả của câu hỏi được liên kếtthí dụ). Hơn nữa, các mục trong danh sách của tôi được sắp xếp rõ ràng - có nghĩa là nếu tôi lưu trữ các phần tử trong một bảng khác, tôi sẽ phải sắp xếp chúng mỗi khi tôi truy cập chúng. Cuối cùng, danh sách về cơ bản là nguyên tử ở chỗ bất cứ khi nào tôi muốn truy cập vào danh sách, tôi sẽ muốn truy cập toàn bộ danh sách thay vì chỉ một phần của nó - vì vậy có vẻ ngớ ngẩn khi phải đưa ra một truy vấn cơ sở dữ liệu để tập hợp các phần của danh sách.

Giải pháp của AKX (được liên kết ở trên) là sắp xếp danh sách và lưu trữ nó trong một cột nhị phân. Nhưng điều này cũng có vẻ bất tiện vì nó có nghĩa là tôi phải lo lắng về tuần tự hóa và giải mã hóa.

Có giải pháp nào tốt hơn không? Nếu có không có giải pháp tốt hơn, thì tại sao? Có vẻ như vấn đề này nên xuất hiện theo thời gian.

... chỉ cần thêm một chút thông tin để cho bạn biết tôi đến từ đâu. Ngay khi tôi vừa mới bắt đầu hiểu về SQL và cơ sở dữ liệu nói chung, tôi đã được bật LINQ to SQL, và vì vậy bây giờ tôi hơi hư hỏng vì tôi mong đợi xử lý mô hình đối tượng lập trình của mình mà không cần phải suy nghĩ về cách các đối tượng. được truy vấn hoặc lưu trữ trong cơ sở dữ liệu.

Cảm ơn tất cả!

John

CẬP NHẬT: Vì vậy, trong loạt câu trả lời đầu tiên tôi nhận được, tôi thấy "bạn có thể đi theo tuyến CSV / XML ... nhưng KHÔNG ĐƯỢC!". Vì vậy, bây giờ tôi đang tìm kiếm lời giải thích tại sao. Chỉ cho tôi một số tài liệu tham khảo tốt.

Ngoài ra, để bạn biết rõ hơn về những gì tôi đang làm: Trong cơ sở dữ liệu của tôi, tôi có một bảng Hàm sẽ có danh sách các cặp (x, y). (Bảng cũng sẽ có thông tin khác không có lợi cho cuộc thảo luận của chúng ta.) Tôi sẽ không bao giờ cần xem một phần của danh sách các cặp (x, y). Đúng hơn, tôi sẽ lấy tất cả chúng và vẽ chúng trên màn hình. Tôi sẽ cho phép người dùng kéo các nút xung quanh để thỉnh thoảng thay đổi giá trị hoặc thêm nhiều giá trị hơn vào biểu đồ.

Câu trả lời:


182

Không, không có cách nào "tốt hơn" để lưu trữ một chuỗi các mục trong một cột duy nhất. Cơ sở dữ liệu quan hệ được thiết kế đặc biệt để lưu trữ một giá trị cho mỗi tổ hợp hàng / cột. Để lưu trữ nhiều giá trị, bạn phải tuần tự hóa danh sách của mình thành một giá trị duy nhất để lưu trữ, sau đó giải mã hóa nó khi truy xuất. Không có cách nào khác để thực hiện những gì bạn đang nói (bởi vì những gì bạn đang nói là một ý tưởng tồi, nói chung, không bao giờ nên làm ).

Tôi hiểu rằng bạn nghĩ thật ngớ ngẩn khi tạo một bảng khác để lưu trữ danh sách đó, nhưng đây chính xác là những gì cơ sở dữ liệu quan hệ làm. Bạn đang chiến đấu với một trận chiến khó khăn và vi phạm một trong những nguyên tắc cơ bản nhất của thiết kế cơ sở dữ liệu quan hệ mà không có lý do chính đáng. Vì bạn trạng thái đó bạn chỉ cần học SQL, tôi sẽ mạnh mẽ khuyên bạn nên tránh ý tưởng này và dính với các khuyến nghị thực hành cho bạn bởi nhà phát triển SQL dày dạn hơn.

Nguyên tắc bạn đang vi phạm được gọi là biểu mẫu chuẩn đầu tiên , đây là bước đầu tiên trong quá trình chuẩn hóa cơ sở dữ liệu.

Trước nguy cơ đơn giản hóa mọi thứ, chuẩn hóa cơ sở dữ liệu là quá trình xác định cơ sở dữ liệu của bạn dựa trên dữ liệu là gì , để bạn có thể viết các truy vấn hợp lý, phù hợp với nó và có thể duy trì nó một cách dễ dàng. Chuẩn hóa được thiết kế để hạn chế sự mâu thuẫn logic và hỏng hóc trong dữ liệu của bạn và có rất nhiều cấp độ đối với nó. Bài viết trên Wikipedia về chuẩn hóa cơ sở dữ liệu thực sự khá tốt.

Về cơ bản, quy tắc (hoặc dạng) chuẩn hóa đầu tiên nói rằng bảng của bạn phải đại diện cho một mối quan hệ. Điều này có nghĩa rằng:

  • Bạn phải có khả năng phân biệt một hàng với bất kỳ hàng nào khác (nói cách khác, bảng của bạn phải có một thứ gì đó có thể dùng làm khóa chính. Điều này cũng có nghĩa là không có hàng nào được trùng lặp.
  • Mọi thứ tự của dữ liệu phải được xác định bởi dữ liệu, không phải bởi thứ tự vật lý của các hàng (SQL dựa trên ý tưởng về một tập hợp, có nghĩa là thứ tự duy nhất bạn nên dựa vào là thứ tự bạn xác định rõ ràng trong truy vấn của mình)
  • Mọi giao điểm hàng / cột phải chứa một và chỉ một giá trị

Điểm cuối cùng rõ ràng là điểm nổi bật ở đây. SQL được thiết kế để lưu trữ các tập hợp của bạn cho bạn, chứ không phải cung cấp cho bạn một "thùng" để bạn tự lưu trữ một tập hợp. Có, có thể làm được. Không, thế giới sẽ không kết thúc. Tuy nhiên, bạn đã tự làm mình khó hiểu SQL và các phương pháp hay nhất đi kèm với nó bằng cách ngay lập tức sử dụng ORM. LINQ to SQL thật tuyệt vời, giống như máy tính đồ thị. Tuy nhiên, theo cách tương tự, chúng không nên được sử dụng để thay thế cho việc biết các quy trình mà chúng sử dụng thực sự hoạt động như thế nào.

Danh sách của bạn bây giờ có thể hoàn toàn là "nguyên tử" và điều đó có thể không thay đổi đối với dự án này. Tuy nhiên, bạn sẽ có thói quen làm những việc tương tự trong các dự án khác, và cuối cùng (có khả năng nhanh chóng) bạn sẽ gặp phải một tình huống mà bây giờ bạn đang phù hợp với danh sách-trong-một cột nhanh-n-dễ-dàng của mình tiếp cận nơi nó hoàn toàn không phù hợp. Không có nhiều công việc bổ sung trong việc tạo bảng chính xác cho những gì bạn đang cố gắng lưu trữ và bạn sẽ không bị các nhà phát triển SQL khác chê bai khi họ nhìn thấy thiết kế cơ sở dữ liệu của bạn. Bên cạnh đó, LINQ to SQL sẽ thấy mối quan hệ của bạn và cung cấp cho bạn giao diện hướng đối tượng thích hợp để danh sách của bạn tự động . Tại sao bạn lại từ bỏ sự tiện lợi do ORM cung cấp cho bạn để bạn có thể thực hiện việc hack cơ sở dữ liệu không chuẩn và không được khuyến khích?


17
Vì vậy, bạn tin chắc rằng việc lưu trữ một danh sách trong một cột là một ý tưởng tồi, nhưng bạn không đề cập đến lý do tại sao. Vì tôi chỉ mới bắt đầu với SQL, một chút "tại sao" thực sự sẽ rất hữu ích. Ví dụ, bạn nói rằng tôi đang "đánh một trận chiến khó khăn và vi phạm một trong những nguyên tắc cơ bản nhất của thiết kế cơ sở dữ liệu quan hệ mà không có lý do chính đáng" ... vậy nguyên tắc là gì? Tại sao những lý do mà tôi viện dẫn là "không tốt"? (đặc biệt là các sắp xếp và tính chất nguyên tử của danh sách của tôi)
JnBrymn

6
Về cơ bản, nó phụ thuộc vào nhiều năm kinh nghiệm được đúc kết thành các phương pháp hay nhất. Hiệu trưởng cơ bản được đề cập đến được gọi là Mẫu đơn Bình thường 1 .
Toby

1
Cảm ơn Adam. Rất nhiều thông tin. Điểm tốt với câu hỏi cuối cùng của bạn.
JnBrymn

8
“[…] Và bạn sẽ không bị các nhà phát triển SQL khác chê bai khi họ nhìn thấy thiết kế cơ sở dữ liệu của bạn.” Có những lý do rất tốt để tôn trọng Biểu mẫu Thông thường Đầu tiên (và câu trả lời của bạn đề cập đến chúng), nhưng áp lực từ bạn bè / “đó là cách mọi thứ được thực hiện ở đây” không nằm trong số đó.
Lynn,

5
Chúng tôi đã lưu trữ nhiều nhóm danh sách trong các cột cơ sở dữ liệu mỗi ngày. Chúng được gọi là "char" và "varchar". Tất nhiên trong Postgres, chúng còn được gọi là văn bản. Điều mà 1NF thực sự nói là bạn không bao giờ nên chia nhỏ thông tin trong bất kỳ trường nào thành các trường nhỏ hơn, và nếu bạn làm như vậy, bạn đã chết tiệt. Vì vậy, bạn không lưu trữ tên, bạn lưu trữ tên cá nhân, tên đệm và họ (tùy thuộc vào bản địa hóa) và ghép chúng lại với nhau. Nếu không, chúng tôi sẽ không lưu trữ các chuỗi văn bản. Mặt khác, tất cả những gì anh ta muốn là một chuỗi dây. Và có nhiều cách để làm điều đó.
Haakon Løtveit

15

Bạn chỉ có thể quên tất cả SQL và sử dụng phương pháp "NoSQL". RavenDB , MongoDBCouchDB là những giải pháp khả thi. Với cách tiếp cận NoSQL, bạn không sử dụng mô hình quan hệ..bạn thậm chí không bị ràng buộc vào các lược đồ.


11

Những gì tôi đã thấy nhiều người làm là điều này (nó có thể không phải là cách tiếp cận tốt nhất, hãy sửa cho tôi nếu tôi sai):

Bảng mà tôi đang sử dụng trong ví dụ được đưa ra bên dưới (bảng bao gồm các biệt hiệu mà bạn đã đặt cho các bạn gái cụ thể của mình. Mỗi bạn gái có một id duy nhất):

nicknames(id,seq_no,names)

Giả sử, bạn muốn lưu trữ nhiều biệt hiệu dưới một id. Đây là lý do tại sao chúng tôi đã bao gồm một seq_notrường.

Bây giờ, hãy điền các giá trị này vào bảng của bạn:

(1,1,'sweetheart'), (1,2,'pumpkin'), (2,1,'cutie'), (2,2,'cherry pie')

Nếu bạn muốn tìm tất cả các tên mà bạn đã đặt cho id 1 người bạn gái của mình thì bạn có thể sử dụng:

select names from nicknames where id = 1;

5

Câu trả lời đơn giản: Nếu và chỉ khi, bạn chắc chắn rằng danh sách sẽ luôn được sử dụng làm danh sách, thì hãy nối danh sách với nhau ở cuối bằng một ký tự (chẳng hạn như '\ 0') sẽ không được sử dụng trong văn bản và lưu trữ. Sau đó, khi bạn truy xuất nó, bạn có thể chia theo '\ 0'. Tất nhiên có những cách khác để thực hiện công cụ này, nhưng những cách đó phụ thuộc vào nhà cung cấp cơ sở dữ liệu cụ thể của bạn.

Ví dụ: bạn có thể lưu trữ JSON trong cơ sở dữ liệu Postgres. Nếu danh sách của bạn là văn bản và bạn chỉ muốn danh sách mà không gặp rắc rối gì thêm, đó là một thỏa hiệp hợp lý.

Những người khác đã mạo hiểm gợi ý về việc tuần tự hóa, nhưng tôi không thực sự nghĩ rằng việc tuần tự hóa là một ý tưởng hay: Một phần của cơ sở dữ liệu là một số chương trình được viết bằng các ngôn ngữ khác nhau có thể nói chuyện với nhau. Và các chương trình được tuần tự hóa bằng cách sử dụng định dạng của Java sẽ không thực hiện tốt tất cả những điều đó nếu một chương trình Lisp muốn tải nó.

Nếu bạn muốn một cách tốt để thực hiện loại điều này, thường có sẵn các kiểu mảng hoặc tương tự. Ví dụ: Postgres cung cấp mảng dưới dạng một kiểu và cho phép bạn lưu trữ một mảng văn bản, nếu đó là những gì bạn muốn và có những thủ thuật tương tự cho MySqlMS SQL bằng cách sử dụng JSON và DB2 của IBM cũng cung cấp một kiểu mảng (trong riêng tài liệu hữu ích ). Điều này sẽ không quá phổ biến nếu không có nhu cầu này.

Những gì bạn mất khi đi trên con đường đó là khái niệm về danh sách như một loạt các thứ theo thứ tự. Ít nhất trên danh nghĩa, cơ sở dữ liệu coi các trường là các giá trị đơn lẻ. Nhưng nếu đó là tất cả những gì bạn muốn, thì bạn nên làm. Đó là một đánh giá giá trị mà bạn phải thực hiện cho chính mình.


3

Ngoài những gì mọi người đã nói, tôi khuyên bạn nên phân tích cách tiếp cận của mình trong thời gian dài hơn bây giờ. Đó là hiện trường hợp mặt hàng là duy nhất. Đó là hiện trường hợp mà resorting các mục sẽ đòi hỏi một danh sách mới. Nó gần như được yêu cầu rằng danh sách hiện đang ngắn. Mặc dù tôi không có thông tin cụ thể về tên miền, nhưng không quá khó để nghĩ rằng những yêu cầu đó có thể thay đổi. Nếu bạn sắp xếp thứ tự danh sách của mình, bạn đang nướng một cách thiếu linh hoạt không cần thiết trong một thiết kế chuẩn hóa hơn. Btw, điều đó không nhất thiết có nghĩa là một mối quan hệ Nhiều: Nhiều đầy đủ. Bạn chỉ có thể có một bảng con duy nhất với khóa ngoại cho phụ huynh và một cột ký tự cho mục.

Nếu bạn vẫn muốn tiếp tục con đường tuần tự hóa danh sách này, bạn có thể cân nhắc việc lưu trữ danh sách bằng XML. Một số cơ sở dữ liệu như SQL Server thậm chí còn có kiểu dữ liệu XML. Lý do duy nhất tôi đề xuất XML là theo định nghĩa, danh sách này cần phải ngắn gọn. Nếu danh sách dài, thì việc sắp xếp nó nói chung là một cách tiếp cận tồi tệ. Nếu bạn đi theo tuyến CSV, bạn cần tính đến các giá trị có chứa dấu phân cách, nghĩa là bạn bắt buộc phải sử dụng các số nhận dạng được trích dẫn. Giả sử rằng danh sách ngắn, có thể sẽ không tạo ra nhiều khác biệt cho dù bạn sử dụng CSV hay XML.


+1 để dự đoán các thay đổi trong tương lai - luôn thiết kế mô hình dữ liệu của bạn để có thể mở rộng.
coolgeek

2

Tôi chỉ lưu trữ nó dưới dạng CSV, nếu đó là các giá trị đơn giản thì đó là tất cả những gì bạn cần (XML rất dài dòng và việc tuần tự hóa đến / từ nó có thể sẽ quá mức cần thiết nhưng đó cũng là một tùy chọn).

Đây là câu trả lời hay về cách rút CSV bằng LINQ.


Tôi mặc dù về điều đó. Nó vẫn có nghĩa là tôi sẽ phải tuần tự hóa và deserialize ... nhưng tôi nghi ngờ điều đó là khả thi. Tôi muốn có một số tha thứ cách để làm những gì tôi muốn, nhưng tôi nghi ngờ không có.
JnBrymn

capnproto.org là một cách để không phải serialize và deserialize, tương tự nhanh (so với CSV hoặc XML) trong trường hợp capnproto không được hỗ trợ bằng ngôn ngữ của bạn lựa chọn msgpack.org/index.html
VoronoiPotato

2

Nếu bạn cần truy vấn trên danh sách, hãy lưu trữ nó trong một bảng.

Nếu bạn luôn muốn danh sách, bạn có thể lưu trữ nó dưới dạng danh sách được phân cách trong một cột. Ngay cả trong trường hợp này, trừ khi bạn có RẤT RẤT lý do cụ thể để không, hãy lưu trữ nó trong một bảng tra cứu.


1

Chỉ có một lựa chọn không được đề cập trong câu trả lời. Bạn có thể hủy bình thường hóa thiết kế DB của mình. Vì vậy, bạn cần hai bảng. Một bảng chứa danh sách thích hợp, một mục trên mỗi hàng, bảng khác chứa toàn bộ danh sách trong một cột (ví dụ: được phân tách bằng dấu hôn mê).

Đây là thiết kế DB 'truyền thống':

List(ListID, ListName) 
Item(ItemID,ItemName) 
List_Item(ListID, ItemID, SortOrder)

Đây là bảng khử chuẩn hóa:

Lists(ListID, ListContent)

Ý tưởng ở đây - bạn duy trì bảng Danh sách bằng cách sử dụng trình kích hoạt hoặc mã ứng dụng. Mỗi khi bạn sửa đổi nội dung List_Item, các hàng thích hợp trong Danh sách sẽ được cập nhật tự động. Nếu bạn chủ yếu đọc danh sách, nó có thể hoạt động khá tốt. Ưu điểm - bạn có thể đọc danh sách trong một câu lệnh. Nhược điểm - cập nhật cần nhiều thời gian và nỗ lực hơn.


0

Nếu bạn thực sự muốn lưu trữ nó trong một cột và để nó có thể truy vấn thì rất nhiều cơ sở dữ liệu hỗ trợ XML ngay bây giờ. Nếu không truy vấn, bạn có thể lưu trữ chúng dưới dạng các giá trị được phân tách bằng dấu phẩy và phân tích cú pháp chúng bằng một hàm khi bạn cần phân tách chúng. Tôi đồng ý với những người khác, mặc dù nếu bạn đang muốn sử dụng cơ sở dữ liệu quan hệ, phần lớn của quá trình chuẩn hóa là tách dữ liệu như vậy. Tôi không nói rằng tất cả dữ liệu đều phù hợp với cơ sở dữ liệu quan hệ. Bạn luôn có thể xem xét các loại cơ sở dữ liệu khác nếu nhiều dữ liệu của bạn không phù hợp với mô hình.


0

Tôi nghĩ trong một số trường hợp nhất định, bạn có thể tạo một danh sách "FAKE" các mặt hàng trong cơ sở dữ liệu, chẳng hạn như hàng hóa có một vài hình ảnh để hiển thị chi tiết của nó, bạn có thể nối tất cả ID của các hình ảnh được chia bằng dấu phẩy và lưu chuỗi vào DB, sau đó bạn chỉ cần phân tích chuỗi khi bạn cần. Tôi đang làm việc trên một trang web và tôi đang dự định sử dụng cách này.


0

Tôi đã rất lưỡng lự khi chọn con đường mà cuối cùng tôi quyết định đi vì rất nhiều câu trả lời. Trong khi họ hiểu thêm về SQL là gì và các nguyên tắc của nó, tôi quyết định trở thành kẻ sống ngoài vòng pháp luật. Tôi cũng do dự khi đăng những phát hiện của mình vì đối với một số người, điều quan trọng hơn là phải trút sự thất vọng cho một người nào đó vi phạm các quy tắc hơn là hiểu rằng có rất ít sự tin tưởng phổ biến.

Tôi đã thử nghiệm nó rộng rãi và trong trường hợp cụ thể của tôi, nó hiệu quả hơn cả việc sử dụng kiểu mảng (được cung cấp bởi PostgreSQL) hoặc truy vấn một bảng khác.

Đây là câu trả lời của tôi: Tôi đã triển khai thành công một danh sách vào một trường duy nhất trong PostgreSQL, bằng cách sử dụng độ dài cố định của mỗi mục trong danh sách. Giả sử mỗi mục là một màu dưới dạng giá trị ARGB, nó có nghĩa là 8 ký tự. Vì vậy, bạn có thể tạo mảng tối đa 10 mục của mình bằng cách nhân với độ dài của mỗi mục:

ALTER product ADD color varchar(80)

Trong trường hợp độ dài các mục trong danh sách của bạn khác nhau, bạn luôn có thể điền vào phần đệm bằng \ 0

NB: Rõ ràng đây không nhất thiết là cách tiếp cận tốt nhất cho số hex vì danh sách các số nguyên sẽ tiêu tốn ít dung lượng hơn nhưng điều này chỉ nhằm mục đích minh họa ý tưởng về mảng này bằng cách sử dụng độ dài cố định được phân bổ cho mỗi mục.

Lý do tại sao: 1 / Rất tiện lợi: lấy mục i tại chuỗi con i * n, (i +1) * n. 2 / Không có phí truy vấn bảng chéo. 3 / Hiệu quả hơn và tiết kiệm chi phí ở phía máy chủ. Danh sách giống như một đốm nhỏ mà khách hàng sẽ phải chia nhỏ.

Mặc dù tôi tôn trọng những người tuân theo các quy tắc, nhưng nhiều giải thích mang tính lý thuyết và thường không thừa nhận rằng, trong một số trường hợp cụ thể, đặc biệt là khi nhắm mục tiêu tối ưu chi phí với các giải pháp có độ trễ thấp, một số chỉnh sửa nhỏ được hoan nghênh hơn cả.

"Chúa cấm rằng nó đang vi phạm một số nguyên tắc thiêng liêng của SQL": Áp dụng một cách tiếp cận cởi mở và thực dụng hơn trước khi đọc thuộc các quy tắc luôn là cách để đi. Nếu không, bạn có thể sẽ giống như một người cuồng tín thẳng thắn đọc lại Ba định luật của người máy trước khi bị Skynet xóa sổ

Tôi không giả vờ rằng giải pháp này là một bước đột phá, cũng không phải là lý tưởng về khả năng đọc và tính linh hoạt của cơ sở dữ liệu, nhưng nó chắc chắn có thể mang lại cho bạn lợi thế khi nói đến độ trễ.


Nhưng đây là một trường hợp rất cụ thể: một số lượng mặt hàng có chiều dài cố định. Thậm chí sau đó, nó thực hiện một tìm kiếm đơn giản như "tất cả các sản phẩm có ít nhất màu x" khó hơn so với SQL chuẩn.
Gert Arnold

Như tôi đã nói nhiều lần, tôi không sử dụng nó cho màu sắc, trường tôi sử dụng nó không nên được lập chỉ mục cũng như không được sử dụng như một điều kiện, và nó là một trường quan trọng
Antonin GAVREL

Tôi biết, tôi đang cố gắng chỉ ra rằng điều này rất cụ thể. Nếu bất kỳ yêu cầu bổ sung nhỏ nào lọt vào đó sẽ nhanh chóng trở nên khó xử hơn các giải pháp tiêu chuẩn. Phần lớn những người bị cám dỗ để lưu trữ danh sách trong một trường db có lẽ tốt hơn là không nên làm điều đó.
Gert Arnold

0

Nhiều cơ sở dữ liệu SQL cho phép một bảng chứa một bảng con như một thành phần. Phương pháp thông thường là cho phép miền của một trong các cột là một bảng. Điều này ngoài việc sử dụng một số quy ước như CSV để mã hóa cấu trúc con theo những cách mà DBMS chưa biết.

Khi Ed Codd phát triển mô hình quan hệ vào năm 1969-1970, ông đã xác định cụ thể một dạng chuẩn không cho phép kiểu lồng các bảng này. Dạng chuẩn sau này được gọi là Dạng chuẩn đầu tiên. Sau đó, ông tiếp tục chỉ ra rằng đối với mọi cơ sở dữ liệu, có một cơ sở dữ liệu ở dạng bình thường đầu tiên thể hiện cùng một thông tin.

Tại sao phải bận tâm với điều này? Chà, cơ sở dữ liệu ở dạng bình thường đầu tiên cho phép truy cập có khóa vào tất cả dữ liệu. Nếu bạn cung cấp tên bảng, giá trị khóa vào bảng đó và tên cột, thì cơ sở dữ liệu sẽ chứa nhiều nhất một ô chứa một mục dữ liệu.

Nếu bạn cho phép một ô chứa danh sách hoặc bảng hoặc bất kỳ bộ sưu tập nào khác, thì bây giờ bạn không thể cung cấp quyền truy cập có khóa vào các mục con mà không hoàn toàn làm lại ý tưởng về khóa.

Quyền truy cập có khóa vào tất cả dữ liệu là cơ bản của mô hình quan hệ. Nếu không có khái niệm này, mô hình không phải là quan hệ. Về lý do tại sao mô hình quan hệ là một ý tưởng tốt, và những hạn chế của ý tưởng tốt đó có thể là gì, bạn phải nhìn vào kinh nghiệm tích lũy có giá trị 50 năm với mô hình quan hệ.


-1

bạn có thể lưu trữ nó dưới dạng văn bản giống như một danh sách và tạo một hàm có thể trả về dữ liệu của nó dưới dạng một danh sách thực tế. thí dụ:

cơ sở dữ liệu:

 _____________________
|  word  | letters    |
|   me   | '[m, e]'   |
|  you   |'[y, o, u]' |  note that the letters column is of type 'TEXT'
|  for   |'[f, o, r]' |
|___in___|_'[i, n]'___|

Và chức năng biên dịch danh sách (được viết bằng python, nhưng nó phải dễ dàng dịch sang hầu hết các ngôn ngữ lập trình khác). TEXT đại diện cho văn bản được tải từ bảng sql. trả về danh sách các chuỗi từ danh sách chứa chuỗi. nếu bạn muốn nó trả về int thay vì chuỗi, hãy đặt chế độ bằng 'int'. Tương tự với 'string', 'bool' hoặc 'float'.

def string_to_list(string, mode):
    items = []
    item = ""
    itemExpected = True
    for char in string[1:]:
        if itemExpected and char not in [']', ',', '[']:
            item += char
        elif char in [',', '[', ']']:
            itemExpected = True
            items.append(item)
            item = ""
    newItems = []
    if mode == "int":
        for i in items:
            newItems.append(int(i))

    elif mode == "float":
        for i in items:
            newItems.append(float(i))

    elif mode == "boolean":
        for i in items:
            if i in ["true", "True"]:
                newItems.append(True)
            elif i in ["false", "False"]:
                newItems.append(False)
            else:
                newItems.append(None)
    elif mode == "string":
        return items
    else:
        raise Exception("the 'mode'/second parameter of string_to_list() must be one of: 'int', 'string', 'bool', or 'float'")
    return newItems

Ngoài ra đây là một chức năng liệt kê thành chuỗi trong trường hợp bạn cần.

def list_to_string(lst):
    string = "["
    for i in lst:
        string += str(i) + ","
    if string[-1] == ',':
        string = string[:-1] + "]"
    else:
        string += "]"
    return string
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.