Mysql
 sql >> база данни >  >> RDS >> Mysql

Съхраняване на матрица на разстоянието в DB

В името на производителността и ако приемем, че използвате InnoDB, вероятно бих денормализирал малко данните, като това:

CREATE TABLE CITY (
    CITY_ID INT PRIMARY KEY
);

CREATE TABLE CITY_DISTANCE (
    CITY1_ID INT,
    CITY2_ID INT,
    DISTANCE NUMERIC NOT NULL,
    PRIMARY KEY (CITY1_ID, DISTANCE, CITY2_ID),
    FOREIGN KEY (CITY1_ID) REFERENCES CITY (CITY_ID),
    FOREIGN KEY (CITY2_ID) REFERENCES CITY (CITY_ID)
);

Всяка двойка градове има 2 реда в CITY_DISTANCE, съдържащи едно и също DISTANCE (по един за всяка посока). Това очевидно може да го направи много голям и може да доведе до несъответствия в данните (базата данни няма да се защити от несъвпадащи стойности на DISTANCE между едни и същи градове), а DISTANCE логично не принадлежи към PK, но имайте търпение...

InnoDB таблиците са групирани , което означава, че като декларираме PK по този конкретен начин, ние поставяме цялата таблица в B-Tree, което е особено подходящо за заявка като тази:

SELECT CITY2_ID, DISTANCE
FROM CITY_DISTANCE
WHERE CITY1_ID = 1
ORDER BY DISTANCE
LIMIT 5

Тази заявка връща най-близките 5 града до града, идентифициран с 1 , и може да бъде удовлетворен чрез просто сканиране на обхват на B-дървото, споменато по-горе:

id  select_type table           type    possible_keys   key     key_len ref     rows    Extra
1   SIMPLE      CITY_DISTANCE   ref     PRIMARY         PRIMARY 4       const   6       "Using where; Using index"

Между другото, InnoDB автоматично ще създаде още един индекс (на CITY2_ID) поради втория FK, който също ще включва CITY1_ID и DISTANCE, тъй като вторичните индекси в клъстерираните таблици трябва да покриват PK. Може да успеете да използвате това, за да избегнете дублирани DISTANCE (изрично създайте индекс на {CITY2_ID, DISTANCE, CITY1_ID} и оставете FK да го използва повторно и ПРОВЕРЕТЕ (CITY1_ID

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как мога да избера всички данни от таблица с условие?

  2. свържете се отдалечено с mysql

  3. Дълбочина в MYSQL и дървета на таблици за затваряне

  4. Sequelize Find принадлежи на много асоциация

  5. Защо EF генерира подзаявка за обикновена заявка?