Прежде всего, здесь уже есть проблема, потому что данные не нормализованы. Создание вида any для группы текстовых столбцов - это то, чего по возможности следует избегать. Даже если эти столбцы не являются текстовыми (и я подозреваю, что они есть), все равно не имеет смысла иметь исполнителя, альбом и в одной таблице. намного лучший дизайн для этого будет:
Artists (
ArtistID int NOT NULL IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
ArtistName varchar(100) NOT NULL)
Albums (
AlbumID int NOT NULL IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
ArtistID int NOT NULL,
AlbumName varchar(100) NOT NULL,
CONSTRAINT FK_Albums_Artists FOREIGN KEY (ArtistID)
REFERENCES Artists (ArtistID))
Songs (
SongID int NOT NULL IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
AlbumID int NOT NULL,
SongName varchar(100) NOT NULL,
NumberOfListens int NOT NULL DEFAULT 0
CONSTRAINT FK_Songs_Albums FOREIGN KEY (AlbumID)
REFERENCES Albums (AlbumID))
Если у вас есть этот дизайн, у вас есть возможность искать отдельные альбомы и исполнителей, а также песни. Вы также можете добавить закрывающие индексы для ускорения запросов, и индексы будут намного меньше и, следовательно, быстрее, чем оригинальный дизайн.
Если вам не нужно выполнять запросы диапазона (что вам, вероятно, не нужно), то вы можете заменить клавишу IDENTITY
на ROWGUID
, если это лучше подходит вашему дизайну; в данном случае это не имеет большого значения, я бы придерживался простого IDENTITY
.
Вы должны быть осторожны с кластеризацией ключей. Если вы кластеризуетесь на ключе, который даже не является удаленно последовательным (а имя исполнителя, альбома и песни определенно считается непоследовательным), то в итоге вы получите разбиение страницы и другие неприятности. Ты не хочешь этого. И, как говорит Марк, копия этого ключа добавляется в каждый индекс, и вы определенно не хотите этого, когда ваш ключ имеет длину 300 или 600 байт.
Если вы хотите иметь возможность быстро запросить количество прослушиваний для конкретной песни по исполнителю, альбому и названию песни, на самом деле это довольно просто с указанным выше дизайном, вам просто нужно правильно проиндексировать:
CREATE UNIQUE INDEX IX_Artists_Name ON Artists (ArtistName)
CREATE UNIQUE INDEX IX_Albums_Artist_Name ON Albums (ArtistID, AlbumName)
CREATE UNIQUE INDEX IX_Songs_Album_Name ON Songs (AlbumID, SongName)
INCLUDE (NumberOfListens)
Теперь этот запрос будет быстрым:
SELECT ArtistName, AlbumName, SongName, NumberOfListens
FROM Artists ar
INNER JOIN Albums al
ON al.ArtistID = ar.ArtistID
INNER JOIN Songs s
ON s.AlbumID = al.AlbumID
WHERE ar.ArtistName = @ArtistName
AND al.AlbumName = @AlbumName
AND s.SongName = @SongName
Если вы посмотрите план выполнения, вы увидите 3 индекса поиска - это так быстро, как вы можете его получить. Мы гарантируем точно такую же уникальность, как и в оригинальном дизайне и , оптимизированном по скорости. Что еще более важно, он нормализован, поэтому и исполнитель, и альбом имеют свою особую индивидуальность, что значительно облегчает управление в долгосрочной перспективе. Гораздо проще найти «все альбомы исполнителя X». Гораздо намного проще и быстрее искать "все песни в альбоме Y".
При проектировании базы данных нормализация должна быть вашей первой задачей, индексация должна быть вашей второй. И вы, вероятно, обнаружите, что, как только у вас будет нормализованный дизайн, лучшая стратегия индексации становится вроде очевидной.