Управление последними версиями строк с группировкой по запросам и как лучше расположить первичный ключ - PullRequest
0 голосов
/ 01 декабря 2010

У меня есть следующая таблица

| Path          | Version | FirstName | LastName |
| People/Frank  | 1       | Frank     | Smith    |
| People/Frank  | 2       | Frank     | Jones    |
| People/Jack   | 1       | Jack      | Johnson  |    

Я бы хотел, чтобы мой запрос возвращал Path и Max Version для всех строк, соответствующих заданному критерию.

В настоящее время я делаю это;

select Path, MAX(Version) as Version from Table where FirstName = 'Frank' group by Path;

Это действительно критичная для производительности часть кода, и мне интересно, могу ли я что-то конкретное сделать с сервером sql, чтобы сделать это быстрее, или если что-то упущено.

Кроме того, я хотел бы убедиться, что мои ограничения определены правильно. Я ожидаю, что запросы будут содержать какие-либо или все столбцы, которые не являются путем и версией, так что вы можете в вышеупомянутом случае запросить либо FirstName, LastName, либо оба. Моя таблица создания sql выглядит так:

create table Index_PersonByFirstName(
   FirstName NVarChar(100) not null, 
   LastName NVarChar(100) not null, 
   Path NVarChar(100) not null, 
   Version Int not null, 

   constraint pk_Index_PersonByFirstName primary key(
      FirstName, 
      LastName, 
      Path, 
      Version), 

    constraint uc_Index_PersonByFirstName_Path_Version unique (
      Path, 
      Version), 

    constraint fk_People_Path_Version foreign key (
      Path, 
      Version) REFERENCES People(Path, Version))

Имеет ли смысл удалить Path из первичного ключа, поскольку он никогда не запрашивается напрямую?

Другой вариант, который я рассмотрел, - это наличие столбца, который указывает, является ли строка «последней» версией для данного пути, и обновление старых строк при записи нового, но это выглядит странно.

Ваши мысли будут высоко оценены. Если я недостаточно подробно изложил, пожалуйста, дайте мне знать, и я добавлю любую другую необходимую информацию.

1 Ответ

1 голос
/ 01 декабря 2010

Запрос в порядке. Это учебник правильный способ сделать это.

Первичным ключом должен быть минимальный набор полей, однозначно идентифицирующих запись. Ваш пример выше вашей реальной базы данных или просто упрощенный или гипотетический пример? Потому что вряд ли имя и фамилия могут быть уникальными. Вы уверены, что у вас никогда не будет двух "Джима Смита"? Я не знаю, как определяется «путь». Может быть, это под вашим контролем, чтобы вы могли гарантировать его уникальность.

Не добавляйте поля в первичный ключ только потому, что это то, что вы хотите отсортировать или выбрать. Для этого используйте альтернативные индексы.

Обновление на основе диких догадок о ваших примерах

Я не знаю, что означают ваши данные или что вы пытаетесь сделать. Но я предполагаю, что имя и фамилия действительно зависят от пути. То есть у вас не будет:

path        vers first name  last name
----        ---- ----------  ---------
/foo/fredm  1    Fred        Miller
/foo/fredm  2    Fred        Miller
/foo/fredm  1    Sally       Jones

Если это так, то у вас действительно должна быть таблица с путем, именем, фамилией, возможно, другими данными и ключом пути. Затем отдельная таблица с путем и версией, а также любые данные зависят от версии.

В противном случае ваша база данных может содержать противоречивые данные. Если путь должен отображаться только на одно имя, что произойдет, если по какой-либо кодировке или ошибке ввода данных вы получите одну запись с путем "fredm" и именем "Fred Miller" и другую с путем "fredm" и именем "Фрэнк Мендель"? Запросы, ожидающие, что они всегда будут одинаковыми, могут в конечном итоге выбрать один случайным образом и дать противоречивые результаты, или вы можете получить две записи, в которых, по вашему мнению, должна быть одна и т. Д. хранить избыточные данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...