Để có Chỉ mục một phần giống như PostgreSQL trong MySQL 5.5


9

Tôi có dữ liệu lớn trong đó tôi chỉ chọn một khoảng nhỏ dữ liệu tại một thời điểm sao cho lựa chọn luôn theo một chuỗi. Tôi đang cố gắng triển khai PostgreSQL như Chỉ mục một phần trong MySQL được nhắm mục tiêu cho các mục đích đó. Tôi không chắc chắn nếu ràng buộc một phần duy nhất giống như ràng buộc mà tôi muốn.

Mã trong PostgreSQL 9.4

CREATE UNIQUE INDEX dir_events
    ON events (measurement_id)
    USING btree
    (eventBody)
    WHERE is_active;

Cố gắng vào chỉ mục một phần của ypercube trong MySQL

CREATE UNIQUE INDEX dir_events
    [index_type] -- TODO what here?
    ON events (measurement_id, is_active)
    [index_type] -- TODO what here?

Làm thế nào bạn có thể tạo chỉ mục một phần giống như PostgreSQL trong MySQL 5.5 hoặc tương tự?


4
MySQL đã không thực hiện các chỉ mục một phần. Bạn có thể thêm một bảng khác trong thiết kế chỉ lưu trữ các hàng có is_active = TRUE(hoặc chỉ có một cột, PK của dir_events).
ypercubeᵀᴹ

Câu trả lời:


13

Cả MySQL và anh chị em (MariaDB, Drijection, v.v.) đều không thực hiện các chỉ mục một phần.

Những gì bạn có thể làm, với sự hạn chế này trong tâm trí:

  • a) tạo một chỉ mục đơn giản (không phải một phần) trên (is_active, measurement_id). Nó sẽ được sử dụng trong các truy vấn trong đó chỉ mục một phần sẽ. Tất nhiên, nếu is_activecột là 3% Đúng và 97% sai, chỉ số này sẽ lớn hơn nhiều (so với chỉ mục một phần). Nhưng vẫn nhỏ hơn bảng và hữu ích cho các truy vấn này.
    Một hạn chế khác là chỉ số không thể UNIQUEvới giải pháp này nên ràng buộc không được thi hành. Nếu chỉ mục được tạo bằng UNIQUE, tính duy nhất cũng sẽ được thực thi cho các hàng is_active = FALSE. Tôi cho rằng bạn không muốn điều đó:

    CREATE INDEX dir_events
        ON events (is_active, measurement_id)
        USING btree ;
  • b1) (biến thể đơn giản của b): thêm một bảng khác trong thiết kế của bạn, chỉ với các cột khóa chính eventsvà một khóa ngoại events. Bảng này chỉ nên có các hàng trong đó is_activelà đúng trong bảng gốc (điều này sẽ được thực thi bởi ứng dụng / thủ tục của bạn). Các truy vấn is_active = TRUEsẽ được thay đổi để tham gia vào bảng đó (thay vì WHEREđiều kiện.)
    Không UNIQUEđược thực thi với giải pháp này nhưng các truy vấn sẽ chỉ thực hiện một phép nối đơn giản (với chỉ mục nhỏ hơn nhiều) và khá hiệu quả:

    CREATE TABLE events_active
    ( event_id INT NOT NULL,         -- assuming an INT primary key on events
      PRIMARY KEY (event_id),
      FOREIGN KEY (event_id)
        REFERENCES events (event_id)
    ) ;
    
    INSERT INTO events_active 
      (event_id)
    SELECT event_id
    FROM events
    WHERE is_active = TRUE ;
  • b2) một giải pháp phức tạp hơn: thêm một bảng khác trong thiết kế của bạn, chỉ với các cột khóa chính của bảng measurement_id . Như trong đề xuất trước, bảng này chỉ nên có các hàng trong đó is_activelà đúng trong bảng gốc (điều này cũng sẽ được áp dụng bởi ứng dụng / thủ tục của bạn). Sau đó, chỉ sử dụng bảng này cho các truy vấn có WHERE is_active = TRUEvà chỉ cần measurement_idcột. Nếu cần nhiều cột hơn events, bạn sẽ phải join, như trước đây.
    Các UNIQUEràng buộc có thể được thực thi với giải pháp này. Việc sao chép measurement_idcột cũng có thể được bảo mật để thống nhất (có thêm một ràng buộc duy nhất eventsvà khóa ngoại tổng hợp):

    ALTER TABLE events
      ADD UNIQUE (event_id, measurement_id) ;
    
    CREATE TABLE events_active
    ( event_id INT NOT NULL,
      measurement_id INT NOT NULL.
      PRIMARY KEY (event_id, measurement_id),
      UNIQUE (measurement_id),
      FOREIGN KEY (event_id, measurement_id)
        REFERENCES events (event_id, measurement_id)
    ) ;
    
    INSERT INTO events_active 
      (event_id, measurement_id)
    SELECT event_id, measurement_id
    FROM events
    WHERE is_active = TRUE ;
  • c) có thể là đơn giản nhất trong tất cả: sử dụng PostgreSQL. Tôi chắc chắn có các gói cho bản phân phối Linux của bạn. Chúng có thể không phải là phiên bản mới nhất của Postgres nhưng chỉ mục một phần đã được thêm vào trong 7.0 (hoặc trước đó?) Vì vậy bạn không gặp vấn đề gì. Thêm vào đó, tôi tự tin rằng bạn có thể cài đặt phiên bản mới nhất trong hầu hết mọi bản phân phối Linux - ngay cả với một chút rắc rối. Bạn chỉ cần cài đặt nó một lần.


Câu trả lời chính xác. Segway: wiki về chỉ mục một phần trích dẫn một blog "Trong MySQL, thuật ngữ" chỉ mục một phần "đôi khi được sử dụng để chỉ các chỉ mục tiền tố" không được nêu trong tài liệu MySQL. Đó là thuật ngữ nhầm lẫn đặt ra trên blog đó. Blog cũng tuyên bố rằng các chỉ mục tiền tố là nhỏ hơn / hiệu suất, sẽ phụ thuộc. Một tiền tố chuỗi sẽ tạo ra một btree với độ sâu ít hơn, nhưng nhiều trang hơn trên mỗi lá, do đó quét chỉ mục có thể nhanh hơn; Tìm kiếm sẽ chậm hơn. Ngoài ra, sử dụng PostgreSQL! PG đầu tiên tôi đề cập đến là tài liệu op-ed kỳ lạ này trong v7.0 postgresql.org/docs/7.0/partial-index.htmlm
Davos

0

Điều đó không lý tưởng, nhưng nếu bạn có xác nhận trên trường, bạn có thể thực hiện thay đổi làm cho giá trị không hợp lệ. Ví dụ các ký tự không hợp lệ, hoặc số âm. Bạn có thể thực hiện thay đổi này khi xóa mềm và bạn biết rằng nó sẽ không xung đột với một giá trị hợp lệ. Bạn cũng cần phải xem các giá trị bị xóa mềm không va chạm với nhau.

Trong 1 trường hợp, tôi đã có một cột email với một ràng buộc duy nhất và id số nguyên tự động cho mỗi hàng. Khi xóa mềm, tôi đã thêm "id @", trong đó id là ID hàng duy nhất, trước email thực. @không được phép trong email trừ khi được trích dẫn, vì vậy tôi biết không có email hợp lệ nào sẽ đụng độ với giá trị mới, và vì vậy điều này sẽ không bao giờ xung đột với một email hợp lệ. ID số nguyên duy nhất cũng đảm bảo mỗi hàng bị xóa sẽ là duy nhất, ngay cả khi cùng một email bị xóa nhiều lần.

Tôi biết điều này không lý tưởng, nhưng nó là một cách đơn giản để giải quyết vấn đề.

LƯU Ý: Thay đổi tôi đề cập thêm các ký tự vào trường duy nhất, vì vậy tôi phải thực hiện các thủ thuật bổ sung để xem giá trị hiện tại đã ở / gần độ dài tối đa. Chúng là ứng dụng cụ thể, vì vậy không đáng để đề cập ở đây, nhưng hãy chú ý và đưa ra cách giải quyết cho điều đó và đây là một cách đơn giản để khắc phục việc thiếu tính năng chỉ mục một phần.

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.