Индексирование URL в SQL Server 2005 - PullRequest
3 голосов
/ 05 октября 2008

Каков наилучший способ хранения и индексации URL-адресов в SQL Server 2005?

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

Проблема в том, что URL-адреса могут быть очень большими, и использование их в качестве ключа делает индексы больше и медленнее. Сколько я не знаю, но я много раз читал, используя большие поля для индексации, следует избегать. Предполагая, что URL - это nvarchar (400), они являются огромными полями для использования в качестве первичного ключа.

Какие есть альтернативы?

Какова будет большая вероятность использования URL-адреса в качестве ключа вместо поля меньшего размера.

Я просмотрел таблицу WebPage, имеющую столбец идентификаторов, а затем использовал ее в качестве первичного ключа для WebPage. Это уменьшает размер всех связанных индексов и делает их более эффективными, но это затрудняет импорт данных. Каждый импорт для связанных таблиц должен сначала искать, какой идентификатор URL, прежде чем вставлять данные в таблицы.

Я также поиграл с использованием хеша для URL, чтобы создать меньший индекс, но все еще не уверен, что это лучший способ сделать что-то. Это не будет уникальный индекс и будет подвержен небольшому количеству коллизий. Поэтому я не уверен, какой внешний ключ будет использован в этом случае ...

Там будут миллионы записей о веб-страницах, хранящихся в базе данных, и будет много пакетных обновлений. Также будет много активности чтения и агрегирования данных.

Есть мысли?

Ответы [ 6 ]

4 голосов
/ 05 октября 2008

Я бы использовал обычный столбец идентификаторов в качестве первичного ключа. Вы говорите:

Это делает все связанные индексы меньшими и более эффективными но это делает импорт данных немного болезненным. Каждый импорт для связанные таблицы должны сначала искать, что идентификатор URL перед вставкой данных в таблицы.

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

В SQL Server 2005 вы можете создать пользовательскую функцию GetUrlId, которая будет выглядеть примерно так:

CREATE FUNCTION GetUrlId (@Url nvarchar(400)) 
RETURNS int
AS BEGIN
  DECLARE @UrlId int
  SELECT @UrlId = Id FROM Url WHERE Url = @Url
  RETURN @UrlId
END

При этом будет возвращен идентификатор для URL, уже имеющихся в вашей таблице URL, и NULL для любого URL, который еще не записан. Затем вы можете вызвать эту функцию, встроенную в ваши операторы импорта - что-то вроде

INSERT INTO 
  UrlHistory(UrlId, Visited, RemoteIp) 
VALUES 
  (dbo.GetUrlId('http://www.stackoverflow.com/'), @Visited, @RemoteIp)

Возможно, это медленнее, чем правильный оператор соединения, но для одноразовых или случайных процедур импорта это может упростить задачу.

2 голосов
/ 05 октября 2008

Разбейте URL на столбцы, основываясь на битах, которые вас интересуют, и используйте RFC в качестве руководства. Отмените информацию о хосте и домене, чтобы индекс мог группироваться как домены (это делает Google).

stackoverflow.com      -> com.stackoverflow  
blog.stackoverflow.com -> com.stackoverflow.blog

У Google есть статья с описанием того, что они делают, но сейчас я не могу их найти.

http://en.wikipedia.org/wiki/Uniform_Resource_Locator

1 голос
/ 07 октября 2008

"Предполагается, что URL является nvarchar (400)"

Я не думаю, что URL должен быть nvarchar, обычного varchar должно быть достаточно.

1 голос
/ 05 октября 2008

Я бы придерживался хеш-решения. Это генерирует уникальный ключ с довольно низкой вероятностью столкновения.

Альтернативой может быть создание GUID и использование его в качестве ключа.

0 голосов
/ 07 октября 2008

Не так уж много решений. Еще одна перспектива.

Сохранение общего уникального URI страницы, возможно, лишает смысла конструкцию URI. Предполагается, что каждая косая черта относится к уникальному семантическому пространству внутри домена (является ли это пространство действительным или логическим). Если только URI, которые вы намереваетесь хранить, не являются чем-то вроде www.somedomain.com/p.aspx?id=123456789, то на самом деле может быть лучше разбить один метаданный URI на таблицу, представляющую субдомены, представленные на вашем сайте. .

Например, если вы собираетесь хранить несколько идентификаторов URI раздела «Новости» в той же таблице, что и идентификаторы URI «Обзоры», то вам не хватает хитрости для создания таблицы «Разделы», содержимое которой содержит метаинформацию о раздел и чей собственный идентификатор действует как родительский для всех этих URI в нем.

0 голосов
/ 07 октября 2008

Я полностью согласен с Диланом. Используйте столбец IDENTITY или GUID в качестве суррогатного ключа в вашей таблице WebPage. Это чистый раствор. Мне кажется, поиск идентификатора при импорте не так уж и болезнен.

Использование большого столбца varchar в качестве ключевого столбца тратит много места и влияет на производительность вставки и запросов.

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