Phân tích thêm một số truy vấn tập hợp chính
Trong phần 3 của loạt bài theo dõi ODBC, chúng ta sẽ đi sâu hơn vào việc quản lý các khóa Access cho các bảng được liên kết với ODBC và cách nó sắp xếp và nhóm các truy vấn CHỌN lại với nhau. Trong phần trước, chúng ta đã tìm hiểu cách thực tế một tập bản ghi kiểu dynaset là 2 truy vấn riêng biệt với truy vấn đầu tiên chỉ tìm nạp các khóa của bảng liên kết ODBC, sau đó được sử dụng để điền dữ liệu. Trong bài viết này, chúng ta sẽ nghiên cứu thêm một chút về cách Access quản lý các khóa và cách nó suy ra khóa để sử dụng cho một bảng được liên kết ODBC với các phân nhánh mà nó có. Chúng ta sẽ bắt đầu với việc sắp xếp.
Thêm một sắp xếp vào truy vấn
Bạn đã thấy trong bài viết trước rằng chúng tôi bắt đầu với một SELECT
đơn giản mà không có bất kỳ thứ tự cụ thể nào. Bạn cũng đã thấy cách Access tìm nạp CityID
lần đầu tiên như thế nào và sử dụng kết quả của truy vấn đầu tiên để điền vào các truy vấn tiếp theo để cung cấp sự nhanh chóng cho người dùng khi mở một tập bản ghi lớn. Nếu bạn đã từng gặp trường hợp khi thêm sắp xếp hoặc nhóm vào truy vấn, mọi thứ đột nhiên chậm lại, điều này sẽ giải thích tại sao.
Hãy thêm một loại trên StateProvinceID
trong một truy vấn Access:
SELECT Cities.* FROM Cities ORDER BY Cities.StateProvinceID;Bây giờ nếu chúng ta theo dõi ODBC SQL, chúng ta sẽ thấy đầu ra:
SQLExecDirect: SELECT "Application"."Cities"."CityID" FROM "Application"."Cities" ORDER BY "Application"."Cities"."StateProvinceID" SQLPrepare: SELECT "CityID", "CityName", "StateProvinceID", "Location", "LatestRecordedPopulation", "LastEditedBy", "ValidFrom", "ValidTo" FROM "Application"."Cities" WHERE "CityID" = ? SQLExecute: (GOTO BOOKMARK) SQLPrepare: SELECT "CityID", "CityName", "StateProvinceID", "Location", "LatestRecordedPopulation", "LastEditedBy", "ValidFrom", "ValidTo" FROM "Application"."Cities" WHERE "CityID" = ? OR "CityID" = ? OR "CityID" = ? OR "CityID" = ? OR "CityID" = ? OR "CityID" = ? OR "CityID" = ? OR "CityID" = ? OR "CityID" = ? OR "CityID" = ? SQLExecute: (MULTI-ROW FETCH) SQLExecute: (MULTI-ROW FETCH)Nếu bạn so sánh với dấu vết từ bài viết trước, bạn có thể thấy rằng chúng giống nhau ngoại trừ truy vấn đầu tiên. Access đưa việc sắp xếp vào truy vấn đầu tiên, nơi nó sử dụng để lấy các khóa. Điều đó có ý nghĩa như bằng cách thực thi sắp xếp trên các khóa mà nó sử dụng để xem qua các bản ghi, Access được đảm bảo có sự tương ứng 1-1 giữa vị trí thứ tự của bản ghi và cách sắp xếp nó. Sau đó, nó điền các bản ghi theo cùng một cách. Sự khác biệt duy nhất là chuỗi khóa mà nó sử dụng để điền vào các truy vấn khác.
Hãy xem xét điều gì sẽ xảy ra khi chúng ta thêm GROUP BY
bằng cách đếm các thành phố cho mỗi tiểu bang:
SELECT Cities.StateProvinceID ,Count(Cities.CityID) AS CountOfCityID FROM Cities GROUP BY Cities.StateProvinceID;Theo dõi sẽ xuất ra:
SQLExecDirect: SELECT "StateProvinceID" ,COUNT("CityID" ) FROM "Application"."Cities" GROUP BY "StateProvinceID"Bạn cũng có thể nhận thấy rằng truy vấn hiện mở chậm và mặc dù nó có thể được đặt là tập bản ghi kiểu dynaset, Access đã chọn bỏ qua điều này và về cơ bản coi nó như tập bản ghi loại ảnh chụp nhanh. Điều này có ý nghĩa vì truy vấn không thể cập nhật và vì bạn không thể thực sự điều hướng đến một vị trí tùy ý trong một truy vấn như thế này. Vì vậy, bạn phải đợi cho đến khi tất cả các hàng đã được tìm nạp trước khi bạn có thể tự do duyệt.
StateProvinceID
không thể được sử dụng để định vị một bản ghi vì sẽ có một số bản ghi trong Cities
bàn. Mặc dù tôi đã sử dụng GROUP BY
trong ví dụ này, nó không cần phải là một nhóm khiến Access thay vào đó sử dụng bộ bản ghi loại ảnh chụp nhanh. Sử dụng DISTINCT
ví dụ sẽ có tác dụng tương tự. Một quy tắc ngón tay cái hữu ích để dự đoán liệu Access có sử dụng tập bản ghi kiểu dynaset hay không là hỏi liệu một hàng nhất định trong tập bản ghi kết quả có ánh xạ trở lại chính xác một hàng trong nguồn dữ liệu ODBC hay không. Nếu không đúng như vậy, Access sẽ sử dụng hành vi chụp nhanh ngay cả khi truy vấn được cho là sử dụng dynaset. Do đó, chỉ vì mặc định là tập bản ghi kiểu dynaset, nó không đảm bảo rằng nó sẽ thực sự là tập bản ghi kiểu dynaset. Nó chỉ là một yêu cầu , không phải là nhu cầu.
Xác định khóa sẽ sử dụng để chọn
Bạn có thể đã nhận thấy trong SQL được theo dõi trước đó trong cả bài viết này và bài viết trước, Access đã sử dụng CityID
là chìa khóa. Cột đó đã được tìm nạp trong truy vấn đầu tiên, sau đó được sử dụng trong các truy vấn chuẩn bị tiếp theo. Nhưng làm thế nào Access biết (các) cột nào của bảng được liên kết mà nó phải sử dụng? Xu hướng đầu tiên sẽ nói rằng nó kiểm tra khóa chính và sử dụng khóa đó. Tuy nhiên, điều đó sẽ không chính xác. Trên thực tế, công cụ cơ sở dữ liệu Access sẽ sử dụng SQLStatistics
của ODBC chức năng trong quá trình liên kết hoặc liên kết lại bảng để kiểm tra những chỉ số nào có sẵn. Hàm này sẽ trả về một tập kết quả với một hàng cho mỗi cột tham gia vào một chỉ mục cho tất cả các chỉ số. Tập kết quả này luôn được sắp xếp và theo quy ước, nó sẽ luôn sắp xếp các chỉ số theo nhóm, chỉ số băm và sau đó là các loại chỉ số khác. Trong mỗi loại chỉ mục, các chỉ mục sẽ được sắp xếp theo tên của chúng theo thứ tự bảng chữ cái. Công cụ cơ sở dữ liệu Access sẽ chọn chỉ mục duy nhất đầu tiên mà nó tìm thấy ngay cả khi nó không phải là khóa chính thực sự. Để chứng minh điều này, chúng tôi sẽ tạo một bảng ngớ ngẩn với một số chỉ số kỳ lạ:
CREATE TABLE dbo.SillyTable ( ID int CONSTRAINT PK_SillyTable PRIMARY KEY NONCLUSTERED, OtherStuff int CONSTRAINT UQ_SillyTable_OtherStuff UNIQUE CLUSTERED, SomeValue nvarchar(255) );Sau đó, nếu chúng tôi điền vào bảng một số dữ liệu và liên kết với nó trong Access và mở dạng xem biểu dữ liệu trên bảng được liên kết, chúng tôi sẽ thấy điều này trong ODBC SQL được theo dõi. Tóm lại, chỉ 2 lệnh đầu tiên được bao gồm.
SQLExecDirect: SELECT "dbo"."SillyTable"."OtherStuff" FROM "dbo"."SillyTable" SQLPrepare: SELECT "ID" ,"OtherStuff" ,"SomeValue" FROM "dbo"."SillyTable" WHERE "OtherStuff" = ?Vì
OtherStuff
tham gia vào một chỉ mục được phân nhóm, nó đến trước khóa chính thực sự và do đó được công cụ cơ sở dữ liệu Access chọn để sử dụng trong tập bản ghi kiểu dynaset để chọn một hàng riêng lẻ. Điều đó cũng xảy ra mặc dù thực tế là tên của chỉ mục được phân cụm duy nhất sẽ đặt sau tên của chỉ mục chính. Một chiến thuật để buộc công cụ cơ sở dữ liệu Access chọn một chỉ mục cụ thể cho một bảng sẽ là thay đổi loại của nó hoặc đổi tên tên để nó sắp xếp theo thứ tự bảng chữ cái trong nhóm của loại chỉ mục. Trong trường hợp của SQL Server, các khóa chính thường được nhóm lại và có thể chỉ có một chỉ mục được nhóm lại, vì vậy, thật tình cờ khi đó thường là chỉ mục chính xác cho công cụ cơ sở dữ liệu Access sử dụng. Tuy nhiên, nếu cơ sở dữ liệu SQL Server chứa các bảng có khóa chính không phân biệt và có chỉ mục duy nhất được nhóm lại có thể không phải là lựa chọn tối ưu. Trong trường hợp không có chỉ mục nào được nhóm lại, bạn có thể tác động đến chỉ số duy nhất nào được sử dụng bằng cách đặt tên chỉ mục để nó sắp xếp trước các chỉ số khác. Điều đó có thể hữu ích với phần mềm RDBMS khác, nơi việc tạo chỉ mục nhóm cho khóa chính là không thực tế hoặc không thể thực hiện được. Chỉ mục phía truy cập cho dạng xem SQL được liên kết hoặc bảng không có chỉ mục
Khi liên kết đến dạng xem SQL hoặc bảng SQL không có bất kỳ chỉ mục hoặc khóa chính nào được xác định, sẽ không có chỉ mục nào có sẵn cho công cụ cơ sở dữ liệu Access để sử dụng. Nếu bạn đã sử dụng trình quản lý bảng được liên kết để liên kết một bảng hoặc một chế độ xem SQL không có chỉ mục, bạn có thể đã thấy một hộp thoại như sau:
Nếu chúng tôi chọn ID
, hoàn thành liên kết, mở bảng được liên kết trong dạng xem thiết kế, sau đó hộp thoại lập chỉ mục, chúng ta sẽ thấy điều này:
Nó cho thấy rằng bảng có một chỉ mục có tên là __uniqueindex
nhưng nó không tồn tại trong nguồn dữ liệu ban đầu. Chuyện gì đang xảy ra vậy? Câu trả lời là Access đã tạo một Access-side chỉ mục cho việc sử dụng nó để giúp xác định cái nào có thể được sử dụng làm định danh bản ghi cho các bảng hoặc dạng xem như vậy. Nếu bạn tình cờ liên kết lại các bảng theo chương trình thay vì sử dụng Trình quản lý bảng được liên kết, bạn sẽ thấy cần phải sao chép hành vi để làm cho các bảng được liên kết như vậy có thể cập nhật được. Điều này có thể được thực hiện bằng cách thực hiện lệnh Access SQL:
CREATE UNIQUE INDEX [__uniqueindex] ON SillyTable (ID);Ví dụ:bạn có thể sử dụng
CurrentDb.Execute
để thực thi Access SQL để tạo chỉ mục trên bảng được nối kết. Tuy nhiên, bạn không nên thực thi nó dưới dạng truy vấn chuyển vì chỉ mục không thực sự được tạo trên máy chủ. Việc cho phép cập nhật trên bảng được liên kết đó chỉ vì lợi ích của Access. Cần lưu ý rằng Access sẽ chỉ cho phép chính xác một chỉ mục cho bảng được liên kết như vậy và chỉ khi nó chưa có chỉ mục. Tuy nhiên, bạn có thể thấy rằng việc sử dụng dạng xem SQL có thể là một tùy chọn mong muốn cho các trường hợp thiết kế cơ sở dữ liệu không cho phép bạn sử dụng các chỉ mục được phân nhóm và bạn không muốn sử dụng tên của chỉ mục để thuyết phục công cụ cơ sở dữ liệu Access sử dụng chỉ mục này, không phải chỉ số đó. Bạn có thể kiểm soát rõ ràng chỉ mục và các cột mà nó nên bao gồm khi liên kết dạng xem SQL.
Kết luận
Từ phần trước, chúng ta đã thấy rằng một tập bản ghi kiểu dynaset thường đưa ra 2 truy vấn. Truy vấn đầu tiên thường đề cập đến việc điền vào phần Chúng tôi đã xem xét kỹ hơn cách Access xử lý tập hợp các khóa mà nó sẽ sử dụng cho một tập bản ghi kiểu dynaset. Chúng tôi đã thấy cách Access thực sự sẽ chuyển đổi bất kỳ cách sắp xếp nào từ truy vấn Access ban đầu và sau đó sử dụng nó trong truy vấn tổng hợp khóa. Chúng tôi thấy rằng thứ tự của truy vấn tổng hợp chính ảnh hưởng trực tiếp đến cách dữ liệu trong tập bản ghi sẽ được sắp xếp và trình bày cho người dùng. Điều này cho phép người dùng thực hiện những việc như chuyển đến một bản ghi danh dự dựa trên vị trí thứ tự của danh sách.
Sau đó, chúng tôi thấy rằng việc nhóm và các hoạt động SQL khác ngăn ánh xạ một-một giữa hàng được trả về và hàng gốc sẽ khiến Access xử lý truy vấn Access như thể nó là một tập bản ghi kiểu ảnh chụp nhanh mặc dù yêu cầu tập bản ghi kiểu dynaset.
Sau đó, chúng tôi xem xét cách Access xác định khóa sử dụng để quản lý các bản cập nhật với bảng được liên kết ODBC. Trái ngược với những gì chúng ta có thể mong đợi, nó sẽ không nhất thiết chọn khóa chính của bảng mà chọn chỉ mục duy nhất đầu tiên mà nó tìm thấy, tùy thuộc vào loại chỉ mục và tên của chỉ mục. Chúng tôi đã thảo luận về các chiến lược để đảm bảo rằng Access sẽ chọn đúng chỉ mục duy nhất. Chúng tôi đã xem xét chế độ xem SQL thường không có bất kỳ chỉ mục nào và thảo luận về một phương pháp để chúng tôi thông báo cho Access cách khóa chế độ xem SQL hoặc bảng không có bất kỳ khóa chính nào, cho phép chúng tôi kiểm soát nhiều hơn cách Access sẽ xử lý các bản cập nhật cho các bảng được liên kết ODBC đó.
Trong bài viết tiếp theo, chúng ta sẽ xem xét cách Access thực sự thực thi cập nhật dữ liệu khi người dùng thực hiện thay đổi thông qua truy vấn Access hoặc nguồn bản ghi.
Các Chuyên gia về Quyền truy cập của chúng tôi luôn sẵn sàng trợ giúp. Gọi cho chúng tôi theo số 773-809-5456 hoặc gửi email cho chúng tôi theo địa chỉ [email protected].