Rails - để sử dụng STI hay không, đó là câu hỏi


8

Sáu tháng trước, tôi đã hỏi một câu hỏi về mô hình hóa dữ liệu cho ứng dụng của mình và nhận được một số lời khuyên chỉ cho tôi về STI (xem mô hình dữ liệu Rails - câu hỏi thực tiễn tốt nhất để biết chi tiết).

Tôi chơi xung quanh với nó, làm cho nó hoạt động phần nào, và sau đó bị phân tâm và đưa dự án vào tình trạng gián đoạn.

Tôi mới bắt đầu phát triển lại từ đầu, với lợi ích sau 6 tháng trải nghiệm lập trình / ROR, và tôi lại một lần nữa chạm vào bức tường này khi nói đến việc tạo mô hình các thành phần cho công thức nấu bia của mình.

Để tóm tắt nhanh, giả sử tôi có ba loại thành phần (mạch nha, hoa bia và men) - mỗi loại chia sẻ một vài thuộc tính (tên, giá, nhà cung cấp) nhưng mỗi loại cũng có các thuộc tính cụ thể cho loại thành phần đó. Tất cả chúng đều liên quan (tất cả đều là thành phần) nhưng chúng có "hành vi" khác nhau (ví dụ, ngũ cốc được nghiền và sẽ có logic để xử lý những thứ không áp dụng cho hoa bia / men, v.v ...)

Các thành phần chỉ đủ khác nhau để tôi dự tính chỉ có ba bảng riêng biệt trong db ... nhưng còn bộ điều khiển thì sao? Tôi có thể sử dụng một bộ điều khiển Thành phần duy nhất để quản lý các mô hình riêng biệt không?

Tôi đã đọc về các lựa chọn thay thế cho STI (kế thừa bảng lớp và kế thừa nhiều bảng) nhưng tất cả các giải pháp có vẻ không hợp lý. Có bất kỳ lựa chọn thay thế nào mang lại cho tôi sự tiện lợi của STI (chẳng hạn như nhận tất cả các thành phần, bất kể loại nào, với một truy vấn bảng duy nhất) mà không có nhược điểm (trường null, bảng khó sử dụng khi bạn tiếp tục thêm các lớp con và trường, v.v.)

Xin lỗi, tôi biết câu hỏi này hơi mờ, nhưng tôi cảm thấy mình không thể tìm ra giải pháp sạch và giờ tôi đang cố gắng tìm ra phương pháp nào ngoài kia là xấu xa hơn. Tôi chắc rằng những người khác đã giải quyết vấn đề này và tôi rất muốn nghe những ưu / nhược điểm của các giải pháp khác nhau. Cảm ơn!


2
Không thể trả lời trừ khi bạn đăng mã. Nếu bạn không biết, chỉ cần chọn một và xem nó diễn ra như thế nào. Bạn đang viết mã Ruby, vậy tại sao phải lo lắng quá nhiều về những gì đang diễn ra trong cơ sở dữ liệu? Bạn luôn có thể thay đổi ánh xạ sau này. Có vẻ như bạn sẽ sớm có một cơ sở dữ liệu lớn trong sản xuất.
kevin cline

Tôi sẽ nói rằng tất cả chúng đều là thành phần và thực hiện logic kinh doanh cao hơn nhưng đó chỉ là tôi ... và như @kevincline nói rằng bạn có thể thay đổi nó sau này. Vì chúng có vẻ giống như cùng một bảng, về cơ bản, nó thậm chí sẽ không quá khó.
Rig

Tôi đoán tôi chỉ ghét ý tưởng có các trường vô giá trị trong bảng của mình, nhưng có lẽ tôi chỉ cần vượt qua nó ...
Jim

Câu trả lời:


7

Mặc dù các trường null vĩnh viễn và các bảng lớn khó sử dụng là xấu về mặt khái niệm, nhưng nhìn chung chúng không thực sự gây ra bất kỳ sự kém hiệu quả thực sự nào. Không gian bổ sung được sử dụng bởi các trường null không phải là một cân nhắc quan trọng đối với hầu hết các hệ thống và tốc độ truy vấn sẽ không chậm hơn nếu bạn thiết lập tốt các chỉ mục của mình.

Và lợi ích của STI thường đáng giá (hiệu quả cơ sở dữ liệu bằng cách giảm thiểu các phép nối, và chia sẻ mã đơn giản và DRYness). Vì vậy, nếu bạn sẽ sử dụng một hệ thống SQL truyền thống, chỉ cần học cách bỏ qua sự xấu xí về khái niệm và sử dụng STI. Trường hợp sử dụng của bạn là những gì STI được thiết kế cho.

Điều đó nói rằng, nếu bạn không quá sâu trong chu kỳ phát triển của mình để dự án này được gắn vào hệ thống cơ sở dữ liệu của bạn (và có vẻ như bạn không phải vậy) và bạn sẵn sàng đầu tư một chút thời gian để nghiên cứu / học hỏi, bạn thực sự có thể muốn xem xét một sự thay thế cho SQL (có rất nhiều cái tốt ngoài kia). Hiện tại, lựa chọn phổ biến nhất (và yêu thích cá nhân của tôi) là MongoDB .

MongoDB dựa trên tài liệu thay vì dựa trên lược đồ. Điều này có nghĩa là nó không cứng nhắc về những gì có thể được lưu trữ trong đó. Vì MongoDB không có lược đồ có cấu trúc bắt buộc, trong dự án của bạn, bạn chỉ có thể có một bộ sưu tập ingredients("bộ sưu tập" trong MongoDB giống với "bảng" trong cơ sở dữ liệu SQL). Mỗi ingredienttrong bộ sưu tập này có thể có các trường được chia sẻ như được định nghĩa trong một Ingredientsiêu lớp (các trường này sẽ không được xác định trong chính db). Và các lớp con Malt, HopsYeastcó thể có các trường riêng của chúng (một lần nữa, như được định nghĩa trực tiếp trong các lớp con mô hình này, không phải trong chính db). Đây chính xác là những gì bạn đang tìm kiếm - nó mang đến cho bạn tất cả sự tiện lợi của STI mà không có sự xấu xí về khái niệm của nó.

Phần thưởng bổ sung: Bạn có thể thấy rằng việc sử dụng hệ thống cơ sở dữ liệu NoQuery như thế này cũng sẽ giúp đơn giản hóa các khu vực khác trong ứng dụng của bạn. Trong nhiều (hầu hết?) Các lĩnh vực kinh doanh web phổ biến, NoQuery là lựa chọn tốt hơn SQL, bởi vì các miền web có xu hướng đặc biệt nhiều tài liệu (vì vậy tài liệu là một lựa chọn tự nhiên cho cơ chế lưu trữ).

Tóm tắt: Nếu bạn gắn bó với việc sử dụng cơ sở dữ liệu SQL vì quản trị hoặc một phần ứng dụng của bạn dựa trên nó hoặc nếu không có thời gian để đầu tư vào việc học một cái gì đó mới, chỉ cần đi với STI. Nếu bạn không gắn bó với việc sử dụng cơ sở dữ liệu SQL và bạn có thời gian để tìm hiểu một cái gì đó mới, tôi khuyên bạn nên chuyển sang MongoDB hoặc cơ sở dữ liệu NoQuery dựa trên tài liệu khác.


Tôi thích câu trả lời này. Lời khuyên thiết thực cho tình huống của tôi với phần thưởng thêm của một số lời khuyên để làm cho mọi thứ dễ dàng hơn trong tương lai. Tôi chưa kiểm tra DB của NoQuery, nhưng tôi sẽ điều tra MongoDB - nghe có vẻ hay và vì toàn bộ dự án này thực sự là một trải nghiệm học tập, tôi chắc chắn sẵn sàng thử những điều mới.
Jim
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.