Hệ thống nhiều người thuê với SQL Server 2016, Shard hoặc cách ly Người thuê thông qua cơ sở dữ liệu riêng biệt cho mỗi người thuê?


12

Cho trường hợp sử dụng:

  • Dữ liệu của người thuê không nên nói chuyện chéo, một người thuê không cần dữ liệu của người thuê khác.
  • Mỗi người thuê nhà có thể có khối lượng dữ liệu lịch sử lớn.
  • Máy chủ SQL được lưu trữ trong phiên bản AWS EC2.
  • Mỗi người thuê nhà là xa về địa lý.
  • Có ý định sử dụng các công cụ trực quan của bên thứ ba như PowerBI Embedded
  • Khối lượng dữ liệu dự kiến ​​sẽ tăng theo thời gian
  • Chi phí của hệ thống bị hạn chế.
  • Giải pháp phải được duy trì mà không cần DBA sản xuất 24/7
  • Các giải pháp nên có thể mở rộng quy mô theo chiều ngang.
  • Tổng số người thuê nhà ít hơn 50

Điều gì sẽ là một kiến ​​trúc được đề xuất, có bất kỳ triển khai tham chiếu nào cho trường hợp sử dụng này không? Tôi tin rằng nhiều người có thể đã phải đối mặt với vấn đề này để phát triển phần mềm doanh nghiệp.

Tôi nghĩ rằng đây là một tình huống khác với Xử lý số lượng người thuê ngày càng tăng trong Kiến trúc cơ sở dữ liệu nhiều người thuê . Trường hợp sử dụng được đề cập trong câu hỏi đó liên quan đến số lượng người thuê cao hơn, rất khác với việc có rất ít (50) người thuê nhà lớn. Kiến trúc được đề cập có thể là một giải pháp ở đây, đó là những gì tôi muốn biết thêm.

Câu trả lời:


16

Gotcha với shending là ứng dụng phải biết phân đoạn nào cần truy vấn. Nói chung, điều này được thực hiện bằng cách shending trên một cái gì đó như khách hàng. Tôi sẽ điều chỉnh một trong những bài đăng trên blog cũ của tôi để sử dụng làm câu trả lời của tôi.

Khi bạn đang xây dựng một ứng dụng cho nhiều khách hàng, có hai cách phổ biến để thiết kế (các) cơ sở dữ liệu:

  • Tùy chọn A: Đặt tất cả các máy khách vào cùng một cơ sở dữ liệu
  • Tùy chọn 2: Xây dựng một cơ sở dữ liệu cho mỗi khách hàng

Đưa tất cả các khách hàng vào cùng một cơ sở dữ liệu

Thật đơn giản: chỉ cần thêm bảng Khách hàng ở đầu lược đồ, thêm bảng Khách hàng để đảm bảo mọi người chỉ nhìn thấy dữ liệu của riêng họ và chúng tôi sẽ đi.

Lợi ích của phương pháp này:

Quản lý lược đồ dễ dàng hơn. Khi các nhà phát triển triển khai một phiên bản mới của ứng dụng, họ chỉ phải thực hiện thay đổi lược đồ trong một cơ sở dữ liệu. Không có lo lắng về việc khách hàng khác nhau không đồng bộ hoặc phiên bản sai.

Điều chỉnh hiệu suất dễ dàng hơn. Chúng tôi có thể kiểm tra việc sử dụng chỉ số và thống kê chỉ ở một nơi, thực hiện các cải tiến dễ dàng và xem các hiệu ứng ngay lập tức trên tất cả các khách hàng của chúng tôi. Với hàng trăm hoặc hàng ngàn cơ sở dữ liệu, ngay cả những thay đổi nhỏ nhất cũng có thể khó phối hợp. Chúng tôi có thể kiểm tra nội dung bộ đệm thủ tục của chúng tôi và biết chắc chắn truy vấn hoặc thủ tục lưu trữ nào là chuyên sâu nhất trên toàn bộ ứng dụng của chúng tôi, trong khi nếu chúng tôi sử dụng cơ sở dữ liệu riêng biệt cho mỗi khách hàng, chúng tôi có thể sử dụng truy vấn tổng hợp thời gian khó khăn hơn trong các kế hoạch thực hiện khác nhau.

Dễ dàng hơn để xây dựng một API bên ngoài. Nếu chúng tôi cần cấp quyền truy cập vào toàn bộ cơ sở dữ liệu của mình cho người ngoài để xây dựng sản phẩm, chúng tôi có thể làm điều đó dễ dàng hơn nếu tất cả dữ liệu nằm trong một cơ sở dữ liệu. Nếu API phải xử lý việc nhóm dữ liệu từ nhiều cơ sở dữ liệu trên nhiều máy chủ, thì nó sẽ thêm thời gian phát triển và thử nghiệm. (Mặt khác, điều đó nhiều máy chủ mà điều bắt đầu gợi ý về một hạn chế đối với kịch bản một cơ sở dữ liệu theo quy tắc tất cả: một cơ sở dữ liệu thường có nghĩa là tất cả các tải của chúng tôi chỉ tác động đến một máy chủ cơ sở dữ liệu.) , với PowerBI, việc có tất cả mọi người trong một cơ sở dữ liệu sẽ giúp việc quản lý các kết nối dễ dàng hơn nhiều.

Dễ dàng sẵn sàng cao hơn & khắc phục thảm họa. Thật đơn giản, thực sự đơn giản để quản lý phản chiếu cơ sở dữ liệu, vận chuyển nhật ký, sao chép và phân cụm nếu tất cả những gì chúng ta phải lo lắng chỉ là một cơ sở dữ liệu. Chúng ta có thể xây dựng một cơ sở hạ tầng một cách nhanh chóng.

Đưa mỗi khách hàng vào cơ sở dữ liệu hoặc phân đoạn riêng của mình

Bạn vẫn cần một danh sách khách hàng, nhưng bây giờ nó trở thành một thư mục - đối với mỗi khách hàng, bạn cũng theo dõi phân đoạn mà nó tồn tại. Khi khởi động, ứng dụng của bạn truy vấn bảng này và lưu trữ nó trong RAM. Khi cần dữ liệu cho máy khách, nó sẽ kết nối trực tiếp với phân đoạn đó (cơ sở dữ liệu & máy chủ).

Lợi ích của phương pháp này:

Khôi phục đơn khách hàng dễ dàng hơn. Khách hàng là túi thịt không đáng tin cậy. . dữ liệu khách hàng khác trong cùng một bảng. Khôi phục trong một kịch bản cơ sở dữ liệu khách hàng đơn giản là dễ chết: chỉ cần khôi phục cơ sở dữ liệu của khách hàng. Không ai khác bị ảnh hưởng.

Xuất dữ liệu dễ dàng hơn. Khách hàng thích nhận được dữ liệu của họ. Họ muốn bảo mật khi biết rằng họ có thể lấy dữ liệu của mình bất cứ lúc nào họ muốn, tránh kịch bản khóa nhà cung cấp đáng sợ và họ muốn tự báo cáo. Với dữ liệu của mỗi khách hàng được phân lập vào cơ sở dữ liệu của riêng họ, chúng tôi chỉ cần cung cấp cho họ bản sao lưu cơ sở dữ liệu của riêng họ. Chúng tôi không phải xây dựng API xuất dữ liệu.

Khả năng mở rộng đa máy chủ dễ dàng hơn. Khi ứng dụng của chúng tôi cần nhiều năng lượng hơn mức chúng tôi có thể nhận được từ một máy chủ, chúng tôi có thể phân chia cơ sở dữ liệu giữa nhiều máy chủ. Chúng tôi cũng có thể phân bổ tải theo địa lý, đặt máy chủ ở châu Á hoặc châu Âu để gần gũi hơn với khách hàng.

Điều chỉnh hiệu suất trên mỗi khách hàng dễ dàng hơn. Nếu một số khách hàng sử dụng các tính năng hoặc báo cáo khác nhau, chúng tôi có thể xây dựng một bộ chỉ mục hoặc chế độ xem được lập chỉ mục chuyên biệt chỉ dành cho những khách hàng đó mà không tăng kích thước dữ liệu của mọi người. Cấp, có một số rủi ro ở đây - bằng cách cho phép sự khác biệt về lược đồ giữa các khách hàng, chúng tôi vừa khiến việc triển khai mã của mình trở nên rủi ro hơn một chút và việc quản lý hiệu suất của chúng tôi trở nên khó khăn hơn.

Quản lý an ninh dễ dàng hơn. Miễn là chúng tôi đã khóa bảo mật đúng cách với một người dùng trên mỗi cơ sở dữ liệu, chúng tôi không phải lo lắng về việc Khách hàng X truy cập dữ liệu của Khách hàng Y. Tuy nhiên, nếu chúng tôi chỉ sử dụng một lần đăng nhập cho tất cả mọi người, thì chúng tôi đã không thực sự giải quyết mối quan tâm này.

Cửa sổ bảo trì dễ dàng hơn. Trong một môi trường toàn cầu nơi khách hàng nằm rải rác trên toàn cầu, việc đưa khách hàng ngoại tuyến đi bảo trì sẽ dễ dàng hơn nếu chúng ta có thể làm điều đó theo nhóm hoặc khu vực.

Thứ nào là thứ phù hợp với bạn?

Không có lựa chọn đúng đắn: bạn phải biết điểm mạnh và điểm yếu của chính công ty mình. Hãy lấy hai khách hàng của tôi làm ví dụ.

Công ty A vượt trội trong điều chỉnh hiệu suất phần cứng. Họ thực sự, thực sự rất giỏi trong việc vắt kiệt phần hiệu năng cuối cùng ra khỏi phần cứng và họ không ngại thay thế phần cứng Máy chủ SQL của mình theo chu kỳ 12-18 tháng. (Họ làm mới máy chủ web cứ sau 4 - 6 tháng!) Điểm mạnh của Achilles là các yêu cầu bảo mật và tuân thủ cao. Họ có nhu cầu kiểm toán đáng kinh ngạc, và họ dễ dàng thực hiện các điều khiển chống đạn trên một máy chủ, cơ sở dữ liệu đơn hơn là quản lý các yêu cầu đó trên hàng ngàn cơ sở dữ liệu trên hàng chục máy chủ. Họ đã chọn một cơ sở dữ liệu, một máy chủ, nhiều khách hàng.

Công ty 2 vượt trội về thực tiễn phát triển. Quản lý thay đổi lược đồ và triển khai mã trên hàng ngàn cơ sở dữ liệu không phải là vấn đề đối với họ. Họ có khách hàng trên khắp thế giới và họ đang xử lý các giao dịch thẻ tín dụng cho những khách hàng đó suốt ngày đêm. Họ cần khả năng phân tán tải theo địa lý và họ không muốn thay thế máy chủ trên toàn thế giới cứ sau 12-18 tháng. Họ đã chọn một cơ sở dữ liệu cho mỗi khách hàng và điều đó sẽ được đền đáp khi họ bắt đầu đưa Máy chủ SQL vào Châu Á và Châu Âu cho các khách hàng nước ngoài của họ.


"Trong trường hợp của bạn, với PowerBI, việc có tất cả mọi người trong một cơ sở dữ liệu sẽ giúp việc quản lý kết nối dễ dàng hơn nhiều". Ngay bây giờ PowerBI Embedded không có bảo mật Hàng cấp và do đó, mỗi người thuê trong một cơ sở dữ liệu sẽ gây ra một số nghi ngờ về trường hợp sử dụng này, hãy xem: Community.powerbi.com/t5/Developer/ , bạn có thể vui lòng viết lại thông tin này Điều này hoặc đề nghị một sự thay thế hoặc chính xác sự hiểu biết của tôi?
DS

Ngoài ra, "Đưa mỗi khách hàng vào cơ sở dữ liệu hoặc phân đoạn riêng của mình" bạn có thể giải thích về sự khác biệt ở đây giữa hai đề xuất này
DS

Tôi sẽ chỉ nói rằng việc phải triển khai đến nhiều cơ sở dữ liệu không tệ như bạn tạo ra. Trong năm 2017, chúng tôi có nhiều tùy chọn giúp dễ dàng triển khai các thay đổi đối với cơ sở dữ liệu 1, 5 hoặc 900. Và khi bạn có ngoại lệ cho các khách hàng cụ thể, những thứ này thường có thể được đưa vào các cơ sở dữ liệu đó theo cách mà họ không can thiệp vào mã chung.
Aaron Bertrand

5

Một sự xem xét nữa tôi chưa thấy trong các câu trả lời khác.

Có một thiết kế cho phép nhiều người thuê trong một cơ sở dữ liệu sẽ mang lại sự linh hoạt sau này. Nếu tải / mở rộng quy mô / bảo mật / yêu cầu vị trí địa lý sau đó đề xuất một người thuê nên có một cơ sở dữ liệu riêng biệt, nó có thể được tạo bằng cách khôi phục DB hiện tại trên phiên bản mới. Dữ liệu của những người thuê nhà khác vẫn được bảo vệ bởi bất kỳ cơ chế nào được đưa ra. Dữ liệu đã lỗi thời có thể được xóa từng phần khỏi cơ sở dữ liệu cũ và mới khi thời gian cho phép.

Điều ngược lại là không đúng sự thật. Hợp nhất nhiều cơ sở dữ liệu một bên thuê sẽ đòi hỏi nhiều công việc hơn.


4

Một thực tế làm cho các mô hình nhiều người thuê dễ dàng hơn nhiều, mặc dù nó phá vỡ sự bình thường hóa *, là bao gồm một cột trên mỗi bảng cho người thuê. Bạn có thể gọi nó là TenantID. Bằng cách đó, mọi truy vấn chạy trên cơ sở dữ liệu có thể lọc trên TenantID trên mỗi bảng và bạn có thể sử dụng phân vùng cơ sở dữ liệu để tách dữ liệu cho từng đối tượng thuê và tăng tốc truy vấn bằng cách có các phân vùng được căn chỉnh. Cách này dễ dàng hơn nhiều để có tất cả người thuê trong một cơ sở dữ liệu theo cách này.

* Nó không luôn luôn phá vỡ bình thường hóa, nhưng nó có thể. Ví dụ, nếu bạn có một Personvà một PersonAddressbảng. Các Personbảng sẽ có TenantID, PersonIDnhư Primary Key. Các PersonAddressbảng sẽ có TenantID, PersonID, AddressTypeIDnhư Primary Key với những gì tôi đang thấy.

Thông thường chỉ PersonIDlà đủ, bởi vì bạn có thể tham gia trở lại Personbàn để tìm Tenant. Tôi khuyên bạn nên chuyển TenantIDtiếp tới mọi bảng tiếp theo, ngay cả khi một phím mỏng hơn sẽ hoạt động.

Theo hiểu biết của tôi, việc chuyển bất kỳ thông tin nào đến một bảng có thể được lấy từ dữ liệu khác được coi là phá vỡ sự bình thường hóa. Nhưng có lẽ sử dụng các phím mỏng chỉ là một thực hành tốt nhất.


Cảm ơn, tôi đồng ý với đề xuất này và để thêm vào đầu nó, tôi muốn đề cập đến trường này TenantID phải là một kiểu số nguyên và không phải là GUID, chúng tôi đã đốt cháy theo cách đó để thực hiện.
DS

3
Nhưng ngay cả khi bạn chọn mang TenantID vào các bảng con mà bạn không phải làm, khóa rộng hơn không có nghĩa là chuẩn hóa bị "hỏng". Giống như việc chọn GUID trên IDENTITY (khóa rộng hơn) không phá vỡ sự bình thường hóa, cũng như không chọn khóa tự nhiên rộng hơn thay vì sử dụng thay thế cả.
Aaron Bertrand
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.