Tôi thấy rất phổ biến khi muốn mô hình hóa dữ liệu quan hệ trong các chương trình chức năng của mình. Ví dụ, khi phát triển một trang web tôi có thể muốn có cấu trúc dữ liệu sau đây để lưu trữ thông tin về người dùng của tôi:Mô hình hóa an toàn dữ liệu quan hệ trong Haskell
data User = User
{ name :: String
, birthDate :: Date
}
Tiếp theo, tôi muốn để lưu trữ dữ liệu về thư mà người dùng đăng trên trang web của tôi:
data Message = Message
{ user :: User
, timestamp :: Date
, content :: String
}
có nhiều vấn đề liên quan đến cấu trúc dữ liệu này:
- Chúng tôi không có bất kỳ cách nào phân biệt người dùng với tên tương tự và ngày sinh.
- Dữ liệu người dùng sẽ được sao chép khi tuần tự hóa/deserialisation
- So sánh người dùng yêu cầu so sánh dữ liệu của họ có thể là một hoạt động tốn kém.
- Nội dung cập nhật cho các trường của
User
là mong manh - bạn có thể quên cập nhật tất cả các lần xuất hiện củaUser
trong cấu trúc dữ liệu của bạn.
Các vấn đề này có thể quản lý được trong khi dữ liệu của chúng tôi có thể được biểu diễn dưới dạng cây. Ví dụ, bạn có thể cấu trúc như thế này:
data User = User
{ name :: String
, birthDate :: Date
, messages :: [(String, Date)] -- you get the idea
}
Tuy nhiên, nó có thể có dữ liệu của bạn có hình dạng như một DAG (tưởng tượng bất kỳ mối quan hệ nhiều-nhiều), hoặc thậm chí là một đồ thị nói chung (OK, có lẽ không phải). Trong trường hợp này, tôi có xu hướng để mô phỏng các cơ sở dữ liệu quan hệ bằng cách lưu trữ dữ liệu của tôi trong Map
s:
newtype Id a = Id Integer
type Table a = Map (Id a) a
Đây là loại công trình, nhưng không an toàn và xấu xí cho nhiều lý do:
- Bạn chỉ là một
Id
constructor gọi đi từ tra cứu vô nghĩa. - Khi tra cứu bạn nhận được
Maybe a
, nhưng thường cơ sở dữ liệu có cấu trúc đảm bảo rằng có giá trị. - Đó là vụng về.
- Thật khó để đảm bảo tính toàn vẹn tham chiếu của dữ liệu của bạn.
- Quản lý các chỉ mục (rất cần thiết cho hiệu suất) và đảm bảo tính toàn vẹn của chúng thậm chí còn khó hơn và vụng về hơn.
Hiện có công việc khắc phục những sự cố này không?
Dường như mẫu Haskell có thể giải quyết chúng (như thường lệ), nhưng tôi không muốn phát minh lại bánh xe.
Không những one-to-many mô hình đưa ra ở đây chia sẻ tất cả những nhược điểm của mô hình ban đầu từ câu hỏi? – ehird
@ehird, tôi thực hiện khoảng 10 lần chỉnh sửa mỗi phút, vì vậy tôi nghĩ rằng tôi đã trả lời mối quan tâm của bạn trên đường đi. – dflemstr
Vâng, thực sự. (BTW, trạng thái axit không thực sự phụ thuộc vào ixset; chúng chỉ được thiết kế để sử dụng cùng nhau.) – ehird