2013-04-03 14 views
8

Giả sử chúng ta có bảng Người (tên, họ, địa chỉ, SSN, v.v.).So sánh SQL và mờ

Chúng tôi muốn tìm tất cả các hàng "rất giống" đối với người được chỉ định A. Tôi muốn thực hiện một số loại so sánh logic mờ của A và tất cả các hàng từ bảng Mọi người. Sẽ có một số quy tắc suy luận mờ hoạt động riêng biệt trên một số cột (ví dụ: 3 quy tắc mờ cho tên, 2 quy tắc về họ, 5 quy tắc về địa chỉ)

Câu hỏi là phương pháp nào sau đây sẽ tốt hơn và tại sao?

  1. Thực hiện tất cả các quy tắc mờ như thủ tục lưu trữ và sử dụng một câu lệnh SELECT nặng trả lại toàn bộ hàng mà là "rất giống" để A. Cách tiếp cận này có thể bao gồm sử dụng Soundex, sim số liệu, vv

  2. Thực hiện một hoặc nhiều câu lệnh SELECT đơn giản hơn, trả về kết quả không chính xác, "tương tự" thành A, và sau đó so sánh mờ với A với tất cả các hàng được trả về (bên ngoài cơ sở dữ liệu) để nhận các hàng "rất giống nhau". Vì vậy, so sánh mờ sẽ được thực hiện trong ngôn ngữ lập trình ưu tiên của tôi.

Bảng Mọi người phải có tối đa 500 nghìn hàng và tôi muốn tạo khoảng 500-1000 truy vấn như thế này mỗi ngày. Tôi sử dụng MySQL (nhưng điều này vẫn chưa được xem xét).

+0

Vui lòng cho biết bạn đang sử dụng rdbms nào. –

+0

Tại sao không sử dụng một trường hợp trong lựa chọn của bạn trả về 1 nếu nó tương tự, 0 nếu không, sau đó tổng hợp tất cả các cột. Những người lớn hơn một phạm vi cụ thể nên được trả lại. Có vẻ như một giải pháp đơn giản cho vấn đề của bạn. –

+1

@JesusZamora: Vấn đề là trước hết giá trị của sự tương đồng có thể là nổi (ví dụ 0.43), đó là lý do tại sao tôi đã nói về "sự so sánh mờ". Vấn đề thứ hai là việc đếm giá trị tương tự này khá là phức tạp và tôi không biết phương pháp này sẽ tối ưu hơn. –

Trả lời

3

Tôi không thực sự nghĩ rằng có một câu trả lời dứt khoát vì nó phụ thuộc vào thông tin không có sẵn trong câu hỏi. Dù sao, quá dài cho một bình luận.

DBMS có thể truy xuất thông tin theo chỉ mục. Nó không có ý nghĩa để có một máy chủ db lãng phí thời gian trong tính toán nặng trừ khi nó được dành riêng cho mục đích cụ thể này (như được trả lời bởi @ Adrian).

Do đó, ứng dụng khách của bạn sẽ ủy quyền cho DBMS truy xuất thông tin theo yêu cầu của quy tắc.

Nếu tính toán nhỏ, tất cả có thể được thực hiện trên máy chủ. Khác, kéo nó vào hệ thống khách hàng.

Điểm bất lợi của phương pháp thứ hai là số lượng dữ liệu di chuyển từ máy chủ đến máy khách và số kết nối để thiết lập. Vì vậy, thông thường nó là một sự thỏa hiệp giữa tính toán và truyền dữ liệu trong máy chủ.Một sự cân bằng để đạt được tùy thuộc vào các đặc tính của các quy tắc mờ.

Chỉnh sửa: Tôi đã thấy trong nhận xét rằng bạn gần như chắc chắn phải triển khai mã trong ứng dụng khách. Trong trường hợp đó, bạn nên xem xét một tiêu chí bổ sung, địa phương mã, cho mục đích bảo trì, tức là, cố gắng có tất cả các mã liên quan với nhau, không lây lan giữa các hệ thống (và ngôn ngữ).

1

Vì bạn vẫn đang xem xét DB sử dụng PostgreSQL có mô-đun fuzzystrmatch cung cấp các hàm Levenshtein và Soundex. Ngoài ra, bạn có thể muốn xem mô-đun pg_trm như mô tả here. Có lẽ bạn cũng có thể đặt chỉ mục trên cột bằng cách sử dụng soundex(), do đó bạn sẽ không phải tính toán mỗi lần. Nhưng dường như bạn đã tối ưu hóa quá sớm nên lời khuyên của tôi là kiểm tra bằng pg và tự hỏi liệu bạn có cần tối ưu hóa hay không, những con số bạn cung cấp thực sự dường như không được xem là bạn có hai phút để chạy một truy vấn.

+0

Sử dụng các hàm levenshtein và soundex từ [fuzzystrmatch] (http://www.postgresql.org/docs/current/static/fuzzystrmatch.html) âm thanh khá tốt nếu tôi quyết định sử dụng cách tiếp cận đầu tiên. Tuy nhiên tôi gần như chắc chắn tôi sẽ phải sử dụng thủ tục của riêng tôi cho ít nhất một số các số liệu (quy tắc mờ) để sử dụng các mô-đun này sẽ không giải quyết tất cả mọi thứ. Dù sao tôi vẫn không chắc chắn nếu làm tất cả mọi thứ bên trong DB là tốt hơn và tại sao. –

+0

Và chính xác hơn về các yêu cầu. Sẽ có 500-1000 truy vấn mỗi ngày, nhưng nó sẽ được hoàn thành càng nhanh càng tốt (như ít hơn giờ) –

+0

@ running.t chạy levenshtein() chức năng một lần milion trong một hàng mất ít hơn nửa giây trên máy tính xách tay của tôi , diffrence() tương tự như vậy bạn không nên lo lắng ít nhất về việc làm điều đó trong db. –

2

Tôi muốn nói rằng bạn nên sử dụng các lựa chọn đơn giản để có được các kết quả gần nhất mà bạn có thể mà không cần phải bập bênh cơ sở dữ liệu, sau đó thực hiện nâng hạng nặng trong lớp ứng dụng của bạn. Lý do tôi đề xuất giải pháp này là khả năng mở rộng: nếu bạn làm việc nặng nề trong lớp ứng dụng, vấn đề của bạn là một trường hợp sử dụng hoàn hảo cho giải pháp bản đồ-giảm kiểu trong đó bạn có thể phân phối việc xử lý các điểm tương đồng trên các nút và nhận kết quả của bạn trở lại nhanh hơn nhiều nếu bạn đặt nó thông qua cơ sở dữ liệu; Ngoài ra, theo cách này, bạn sẽ không khóa cơ sở dữ liệu của mình và làm chậm bất kỳ hoạt động nào khác có thể xảy ra cùng một lúc.

+0

Tôi nghĩ đó là cách tôi sẽ thực hiện điều này. Nhưng tôi vẫn tự hỏi liệu có bất kỳ nhược điểm hay rủi ro tiềm tàng nào của phương pháp này hay không. –

+1

Nhược điểm sẽ được dựa trên tình hình của bạn: nếu máy chủ cơ sở dữ liệu của bạn thường có nhiều dung lượng không sử dụng hơn máy chủ ứng dụng của bạn, bạn sẽ muốn giảm tải nhiều công việc hơn cho máy chủ cơ sở dữ liệu. Nếu họ đang ở trên cùng một hộp, bạn phải chuẩn nó cả hai cách để có được câu trả lời tốt nhất cho tình hình cụ thể của bạn. – Adrian

0

Tùy chọn tôi muốn xem xét là thêm cột vào "Mọi người Talbe" là giá trị SoundEx của người đó.

tôi đã thực hiện tham gia sử dụng

Select [Column} 
From People P 
    Inner join TableA A on Soundex(A.ComarisonColumn) = P.SoundexColumn 

Điều đó sẽ quay trở lại bất cứ điều gì trong TableA có giá trị Soundex cùng từ dân Bàn Soundex Cột.

Tôi chưa sử dụng loại truy vấn đó trên bảng có kích thước, nhưng tôi thấy không có vấn đề gì khi thử nó. Bạn cũng có thể lập chỉ mục cho SoundExColumn để trợ giúp hiệu năng.