Cách giảm khớp nối chặt chẽ giữa hai nguồn dữ liệu


10

Tôi gặp một số khó khăn khi tìm một giải pháp thích hợp cho vấn đề kiến ​​trúc sau đây.

Trong cài đặt của chúng tôi (phác họa bên dưới), chúng tôi có 2 nguồn dữ liệu, trong đó nguồn dữ liệu A là nguồn chính cho các mục thuộc loại Foo. Một nguồn dữ liệu thứ cấp tồn tại có thể được sử dụng để lấy thông tin bổ sung trên Foo; tuy nhiên thông tin này không phải lúc nào cũng tồn tại.

Hơn nữa, nguồn dữ liệu A có thể được sử dụng để truy xuất các mục thuộc loại Bar. Tuy nhiên, mỗi thanh đề cập đến một Foo. Khó khăn ở đây là mỗi Thanh nên tham chiếu đến một Foo, nếu có, cũng chứa thông tin được tăng thêm bởi nguồn dữ liệu B.

Câu hỏi của tôi là: làm thế nào để loại bỏ sự kết hợp chặt chẽ giữa subsystemA.1 và DataSourceB?

http://i.stack.imgur.com/Xi4aA.png


10
Đó là một bản phác thảo đẹp. Bạn đã sử dụng chương trình gì để vẽ nó?
Marcelo MD

Tôi cũng muốn biết bạn đã sử dụng chương trình gì để vẽ nó. Xin vui lòng.
Tulains Córdova

2
yuml.me là trang web anh sử dụng nhiều hơn khả năng tạo sơ đồ.
Jason Turner

1
Không DataSourceADataSourceBđã tách rời? DataSourceAcó một sự phụ thuộc vào cả hai SubSystemA.1SubSystemA.2, nhưng không phụ thuộc vào DataSourceB.
Tulains Córdova

1
@fstuijt Không, không phải vậy. Nếu bạn sửa đổi SubsystemA.1để sử dụng một cái gì đó khác DataSourceB, DataSourceAsẽ không biết. DataSourceAchỉ quan tâm mà SubsystemA.1có một getFoo(id)phương pháp. Có một sự trừu tượng giữa DataSourceADataSourceB.
Tulains Córdova

Câu trả lời:


3

Tôi đã tạo ra một ứng dụng có nhiều kiến ​​trúc dữ liệu tương tự đằng sau nó; chúng tôi có cơ sở dữ liệu SQL tại chỗ chứa hầu hết thông tin tự động hóa và nội bộ hàng ngày và sau đó là dịch vụ đám mây của bên thứ ba được sử dụng để bán hàng, quản lý tài khoản, nhân viên hiện trường, v.v. Helpdesk cần thông tin từ cả hai vị trí thực tế của khách hàng và thiết bị, và đã nhận được nó từ hai ứng dụng khác nhau cho đến khi tôi bước vào.

Dài và ngắn là một nguồn dữ liệu cần phải có một tham chiếu đến các bản ghi của dữ liệu kia. Trong trường hợp của chúng tôi, dữ liệu đám mây của bên thứ ba chứa các tham chiếu đến dữ liệu tại chỗ vì đó là sự sắp xếp mà chúng tôi có quyền kiểm soát nhiều nhất. Bây giờ, với ID cho một bản ghi từ một trong hai nguồn dữ liệu, chúng ta có thể lấy dữ liệu từ cả hai; với ID đám mây, chúng tôi lấy bản ghi từ đám mây, lấy ID tại chỗ và kéo dữ liệu tại chỗ. Với ID tại chỗ, chúng tôi thăm dò cả hai nguồn dữ liệu dựa trên ID đó.

Trong hệ thống của tôi, tôi đã không biến đối tượng thành con của người khác trong lớp miền; bất kỳ việc sử dụng dữ liệu từ cả hai cửa hàng đều phải duy trì hai trường hợp đối tượng. Không ai được đảm bảo tồn tại, đó là lý do tại sao tôi đã làm theo cách đó; ứng dụng chỉ có thể hoạt động với dữ liệu đám mây hoặc với dữ liệu tại chỗ hoặc cả hai, với nhiều hạn chế hơn, dữ liệu càng ít.

Tuy nhiên, điều đó không khó để thay đổi, đặc biệt nếu bạn chắc chắn rằng một bên sẽ luôn tồn tại; chỉ cần bao gồm một thuộc tính trong đối tượng đại diện cho phía mà dữ liệu sẽ luôn tồn tại, đó là loại đối tượng đại diện cho bản ghi của kho lưu trữ dữ liệu khác. Nâng cao "hợp nhất" hai biểu đồ thành một là có thể.

Kiểu sắp xếp này nhất thiết phải được ghép ở một số cấp độ. Bạn có thể có một DAL có thể giao tiếp với cả hai kho lưu trữ dữ liệu hoặc bạn có thể phân đoạn các DAL, mỗi DAL cho một kho lưu trữ dữ liệu và có một lớp cao hơn như Bộ điều khiển lấy dữ liệu từ mỗi và gắn chúng lại với nhau. Tuy nhiên, ở một mức độ nào đó, chương trình của bạn phải có thông minh để đặt hai dữ liệu nguồn dữ liệu khác nhau này lại với nhau.

Bạn có thể giảm khớp nối được yêu cầu trong hầu hết các trường hợp bằng cách trừu tượng hóa chi tiết chính xác nơi dữ liệu đến từ đâu. Nếu bạn nhận được dữ liệu từ một dịch vụ web, được cung cấp cho bạn dưới dạng các thể hiện của các lớp được tạo, sau đó đặt một trình chuyển đổi để tạo một bản sao sâu của lớp dịch vụ vào thứ bạn kiểm soát, sẽ không phải thay đổi nếu dữ liệu nguồn nào (chỉ khi lược đồ nào).

Bây giờ, đây có thể là một công việc rất lớn; đám mây chúng ta sử dụng có hàng tá các lớp miền, một số trong đó có hàng trăm trường dữ liệu và - đây là kicker - bạn có thể dễ dàng thực hiện các thay đổi lớn đối với loại dữ liệu trừu tượng để phù hợp với việc di chuyển sang đám mây khác hoặc từ xa khác nguồn dữ liệu. Vì lý do đó, tôi đã không bận tâm; Tôi sử dụng trực tiếp miền dịch vụ web được tạo và bây giờ thay đổi từ kho lưu trữ dữ liệu ngoài đám mây (nhưng dưới sự kiểm soát của chúng tôi) đang xuất hiện, các chi tiết mà tôi vẫn chưa biết, tôi chỉ đơn giản là dự định thay đổi các biểu mẫu và các cơ sở mã của ứng dụng, là nơi dữ liệu được "kết hợp", để phản ánh lược đồ mới và / hoặc các đối tượng dữ liệu. Đó là một công việc lớn, bất cứ cách nào bạn cắt nó.


Câu trả lời này bao gồm tốt nhất vấn đề mà tôi gặp phải, và theo tôi cũng đưa ra câu trả lời tốt nhất cho đến nay. Tuy nhiên, tôi sẽ nghĩ rằng việc kết hợp dữ liệu từ nhiều nguồn là một vấn đề phổ biến. Bất kỳ mẫu thiết kế có thể giúp đỡ?
fstuijt

1
Một số biến thể trên mẫu Factory có thể hữu ích. Nếu bạn có một đối tượng CloudInvoice và SqlInvoice (từ các nguồn dữ liệu tương ứng của họ) và bạn muốn tạo một Hóa đơn thống nhất, hãy tạo một Nhà máy biết đủ về cả hai nguồn dữ liệu để lấy ra một nửa bản ghi mà nó sắp tạo, và sau đó hợp nhất thông tin vào lớp miền của bạn.
KeithS

4

Một cách để giải quyết vấn đề này là tạo một nguồn dữ liệu tổng hợp có chứa dữ liệu từ cả hai nguồn dữ liệu ở một nơi. Một công việc sẽ chạy theo định kỳ để kiểm tra những thay đổi trong các nguồn AB, và viết các "đồng bằng châu thổ" vào nguồn dữ liệu tổng hợp của bạn. Điều này sẽ chuyển đổi hai nguồn dữ liệu được liên kết chặt chẽ thành một nguồn dữ liệu kết hợp duy nhất.

Một số điều có thể ngăn bạn thực hiện phương pháp này:

  • Lượng dữ liệu có thể bị cấm - Một bản sao đầy đủ ABcần phải được thực hiện, nhân đôi yêu cầu về không gian.
  • Dữ liệu được truyền trực tiếp - Sẽ có những khoảng thời gian giữa thời gian dữ liệu trong nguồn thay đổi và công việc tổng hợp đã truyền nó vào nguồn tổng hợp.
  • Bạn cần đối chiếu dữ liệu với các nguồn ban đầu - Nhiệm vụ di chuyển các thay đổi trở lại vị trí ban đầu của chúng trở nên phức tạp hơn rất nhiều nếu bạn thực hiện phương pháp này.

Tôi đồng ý, giới thiệu một lớp trừu tượng là cách tiếp cận ưa thích
neontapir

2
Bạn có thể có một lớp trừu tượng mà không cần sao chép dữ liệu.
smp7d

@ smp7d Điều này sẽ ẩn khớp nối phía sau một mặt trước đẹp; Tuy nhiên, tôi cho rằng bạn đã làm một cái gì đó tương tự trong hệ thống của mình, bởi vì nếu không thì sự phức tạp sẽ được lan truyền trên toàn bộ thiết kế của bạn.
dasblinkenlight

Tùy thuộc vào môi trường DB, điều này cũng có thể được xử lý với một / nhiều Lượt xem, loại bỏ nhu cầu sao chép dữ liệu.
Walter

Không DataSourceADataSourceBđã tách rời? DataSourceAcó một sự phụ thuộc vào cả hai SubSystemA.1SubSystemA.2, nhưng không phụ thuộc vào DataSourceB.
Tulains Córdova

1

Có vẻ như ở cấp cao nhất có hai loại: Foo và Bar và bạn chỉ có hai hành động cấp cao nhất: findFoo(...)findBar(...). Đó là giao diện cho lớp I / O.

Mô tả của bạn trong những nguồn dữ liệu ngụ ý rằng có hai phương pháp trên A: findFoofindBarvà một phương pháp trên B: findFooAuxiliaryInformation. Trong findFoobạn sẽ cần hợp nhất thông tin từ A và B.

Tôi không chắc chắn về "khớp nối chặt chẽ" mà bạn đang đề cập đến. Có ba loại dữ liệu chứa trong hai tập dữ liệu: Bar, Foo, và FooAuxData. Khớp nối giữa FooFooAuxDatavốn có trong dữ liệu đầu vào và không thể giảm. Nhưng khớp nối đó chỉ xuất hiện trong findFoophương thức. Đó là điều tốt nhất bạn có thể làm. Yêu cầu được thực hiện ở một nơi duy nhất. Nếu nó thay đổi, bạn phải thay đổi mã đó.


0

Bạn không thể.

Nếu tôi hiểu chính xác, FooBarđến từ dsA. Bars thuộc về Foos.
Tốt hơn là, bạn không muốn Barđược gán cho Foos, trừ khi Foođã được bổ sung bởi Foo.enhancedInfonó đến từ dsB.

Sở thích của bạn để gán Bars cho Foos là những gì tạo ra khớp nối chặt chẽ của bạn. Tôi sẽ đủ điều kiện là một "thách thức yêu cầu" đang buộc bạn phải đi theo một con đường cụ thể.

Vì vậy, những thách thức kỹ thuật là dsBcó thể có hoặc không có thông tin về bất kỳ điều gì được đưa ra FoodsBthậm chí có thể không có sẵn.

Bạn cần phải quyết định mức độ khó và nhanh của sở thích đó Foo.enhancedInfothực sự là như thế nào . Dựa trên yêu cầu đó, bạn có thể quyết định cung cấp đối tượng Foo+ Barhoặc không. Việc cho phép không tăng cường Foođược cung cấp chỉ làm phức tạp logic và cho tôi biết rằng ưu tiên không nghiêm ngặt như nó có thể xuất hiện. Xác định các biến thể của Foo, Foo.enhancedBar(các) ứng dụng của bạn có thể hỗ trợ và bạn sẽ có câu trả lời cuối cùng.

Có những điều khác bạn có thể làm để di chuyển các Foothông tin liên quan lại gần nhau hơn và điều đó có thể giải quyết một số vấn đề này. Cách câu hỏi của bạn được đặt ra, có vẻ như bạn đang xử lý vấn đề ở cấp đối tượng dữ liệu và bạn có thể không thể xem xét thay đổi loại cơ sở hạ tầng.


Cách khác của vòng: Foo s thuộc về Bar s
fstuijt

@fstuijt Tôi sẽ cập nhật câu trả lời của tôi một chút. Về cơ bản, nó sẽ vẫn như cũ. Bạn cần quyết định cách bạn muốn phục vụ Bar + Foo.

0

Nếu dữ liệu trong nguồn dữ liệu B không thể tự đứng vững, có lẽ bạn sẽ muốn di chuyển nó sang nguồn dữ liệu A nếu có thể.

Nếu chúng độc lập nhưng có liên quan, bạn nên xem xét ảo hóa dữ liệu . Điều này sẽ cho phép các ứng dụng coi dữ liệu là một bộ (khi thích hợp) theo cách thức bất khả tri. Tùy thuộc vào nền tảng của bạn, có thể sẽ có một khung / thư viện hiện có có thể giúp bạn thực hiện điều này.

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.