Должен ли я использовать строки в качестве первичных ключей для веб-сайта, который занимается SEO? - PullRequest
0 голосов
/ 11 августа 2009

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

website.com / Тип / автомобиль / Страна / США / Производитель / Ford / год / 2007

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

Я прочитал ответы на этот вопрос stackoverflow
Строки как первичные ключи в базе данных SQL
Люди там говорят, что это зависит от размера строки и других факторов, но мне кажется, что в этом случае, так как я всегда буду искать строку в разных таблицах, имеет смысл, чтобы эта строка была первичной. Альтернатива состоит в том, чтобы установить целое число в качестве первичного ключа, но я все равно буду искать неосновную строку и выяснять первичный ключ из этого. А из того, что я понимаю о базах данных, это плохая идея, поскольку они хранят данные таким образом, что поиск первичного ключа выполняется быстрее, чем поиск любого другого поля.
Я использую MS SQL Server 2005. Спасибо.

Ответы [ 8 ]

5 голосов
/ 11 августа 2009

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

5 голосов
/ 11 августа 2009

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

Другое (как указал Джош) то, что URL очень похожи, поэтому сравнение будет очень медленным (по сравнению с int) - для двух элементов - 2007 и 2008 внутри website.com/Type/Car/Country/Usa/Manufacturer/Ford/Year/ вам нужно преодолеть много места - 56 символов (плюс три для 200), прежде чем вы попадете в уникального.

3 голосов
/ 11 августа 2009

Пожалуйста, нет.

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

Кроме того, строки гораздо медленнее сравнивать и объединять. Через несколько таблиц и ряд строк это становится болезненным.

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

1 голос
/ 11 августа 2009

Если вы посмотрите на SO URL, то заметите, что они не на самом деле хранят строку для ключа, но идентификатор элемента (вопроса). URL является украшенным с понятным для человека описанием, но это совершенно не имеет отношения к отображению. Итак, открытие URL Должен ли я использовать строки в качестве первичных ключей для веб-сайта, который имеет большое значение для SEO? - это то же самое, что и открытие Должен ли я использовать строки в качестве первичных ключей для веб-сайта, который имеет большое значение в SEO? , что совпадает с открытием https://stackoverflow.com/questions/1258198

Итак, вы видите, что в запросе http и преобразовании URL-адреса происходит не то, что хранится в базе данных. База данных использует идентификаторы int для очевидных причин производительности и хранения, которые уже были рассмотрены в предыдущих ответах.

1 голос
/ 11 августа 2009

Я хотел бы отметить, что существует разница между первичными ключами и кластерными индексами. PK может поддерживаться некластеризованным индексом, и в этом случае вся таблица НЕ переставляется при вставке нового элемента.

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

Существуют довольно веские аргументы в пользу использования естественных ключей (например, описанных вами) для ПК. Просто не располагайте кластеризованный индекс под ним, так как CIX почти никогда не должен находиться в такой строке.

Rob

0 голосов
/ 11 августа 2009

Я не согласен, что целочисленный ключ ВСЕГДА лучше. Конечно, быстрее искать по целому числу. Но если на самом деле доступ, который вы должны сделать, всегда будет или почти всегда будет текстовым значением, то тот факт, что если бы у вас был идентификатор записи для поиска, это было бы намного быстрее, в значительной степени не имеет значения. Если вы заранее знали номер выигрышной лотереи, вы могли бы купить билет с этим номером и стать богатым. Бесспорно верное утверждение, но не полезно, если вы не случится иметь выигрышный лотерейный номер заранее.

Таким образом, реальный вопрос заключается в следующем: что вам нужно хранить в ВАШЕЙ базе данных и как ВЫ должны получить к ней доступ? Если 99% ваших обращений будут «брать URL-адрес и искать запись», то использование URL-адреса или чего-то, что вы извлекаете из URL, возможно, является хорошей идеей.

Мой главный аргумент против этого не в том, что это строка, а в том, что она объединяет множество различных фактов. Вы когда-нибудь заботились о частях? Мол, ты когда-нибудь хотел сказать: «Найди мне все Форды»? Если это так, то «Форд» застрял в середине первичного ключа - очень и очень плохая идея. Единственный способ найти все Форды - это последовательный поиск по всему файлу с поиском символов «Форд» в середине клавиши. Некрасиво. Намного лучше иметь отдельное поле «make», по которому вы можете искать.

Я не знаю ваше приложение, но подозреваю, что переход от URL к записи - не единственный доступ. Есть ли какая-то функция просмотра или поиска, где пользователь может сказать: «Найди мне все кабриолеты, которым меньше 10 лет» или что-то подобное? Если это так, вам действительно нужно разбить данные на отдельные поля, чтобы иметь возможность поиска.

Кроме того, какие данные вы получаете, когда получаете этот URL? Вы получаете только одну запись и показываете ее, или есть много записей, свисающих с нее? Если есть связанные записи, то, если URL является первичным ключом «начальной» записи, тогда все эти связанные записи также должны будут содержать этот большой URL в качестве внешнего ключа. Это может стать грязным. Вы должны учитывать общую структуру вашей базы данных - какие таблицы вам нужны и как они связаны - прежде чем принимать решение об индексах. (Эй, это звучит как хорошее место для добавления бесстыдного плагина для моей книги «Разумный подход к проектированию баз данных», где я обсуждаю вопросы проектирования и порядок, в котором вы должны принимать проектные решения.)

Деталь, но потенциально большая: вам действительно нужны имена подразделений и их значения? То есть вместо того, чтобы указывать URL-адрес «website.com/Type/Car/Country/Usa/Manufacturer/Ford/Year/2007», не может ли это быть просто «website.com/Car/Usa/Ford/2007»? Это устранит много лишнего текста. И, кстати, если вы имеете дело только с одним веб-сайтом, так что все ваши URL начинаются с «website.com», то вам, конечно, не нужно хранить это в каждой записи. О, а порядок значительный? Может кто-нибудь дать URL «webiste.com/Year/2007/Type/Car/Manufacturer/Ford/Country/Usa» и получить ту же информацию? Если так, все становится намного сложнее.

Есть ли здесь что-то кроме автомобилей? Например, может быть «website.com/Type/Pet/Kind/Dog/Breed/Poodle» или что-то подобное? (Или пропуская метки "/ Pet / Dog / Poodle".) Если это так, общая схема использования URL выглядит немного лучше, чем более конкретная схема, которая пытается разбить его на отдельные поля. Может быть.

0 голосов
/ 11 августа 2009

Я думаю, что здесь можно использовать строку в виде PK, потому что список производителей автомобилей небольшой (200?). Даже список кармоделей не такой большой (20000?). Если вы углубитесь в детали, вы больше не будете довольны строковыми ключами. Список дисков / шин для каждого автомобиля очень большой.

Проблема, с которой вы столкнетесь, заключается в том, что вы не можете указать имя в URL-адресе «Alfa Romeo». Чтобы сделать его дружественным для человека, я бы изменил его на «Альфа-Ромео» и назвал его «PK» и «URL», но сохранил исходное имя в качестве читаемого имени. Проблема становится еще хуже с моделями автомобилей.

Особенно французы довольно плохи в этом "Renault Mégane". Для этого вам нужно посмотреть " Unicode-декомпозиция "

Мне кажется, что мне не нравится суррогатный ключ, так как названия автомобилей меняются не так часто, но ваш суррогатный ключ будет меняться.

0 голосов
/ 11 августа 2009
  1. Возможно, вы захотите использовать хэш строки в качестве индекса / ключа вместо самой строки. Это поможет избежать дорогостоящих сравнений строк в запросах.

  2. Могут ли данные пережить схему URL? Вы можете захотеть простой, целочисленный, первичный ключ и вторичный ключ / индекс для строки. Таким образом, если вам нужно пересмотреть свои шаги с помощью строкового индекса, отношения внешнего ключа все еще сохраняются.

  3. Задумывались ли вы, как нормализовать строку URL, чтобы обеспечить правильное сопоставление с записями? например это год == год и Ford / 2007 == 2007 / Ford? Должны ли такие пути отображаться на одну и ту же запись?

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