Дизайн базы данных для тегов или тегов - PullRequest
0 голосов
/ 11 июня 2018

Каким образом теги элемента хранятся в базе данных без проблем?

Каждый элемент имеет несколько тегов.Я прочитал несколько ответов об эффективном способе сделать это:

  1. Какой самый эффективный способ хранения тегов в базе данных?
  2. Рекомендуемый дизайн базы данных SQL для тегов или тегов

Но я думаю, что есть лучшее решение для этого.Почему мы не можем просто включить теги в виде длинной строки для каждого элемента?

 Table : Brand_Shops
 Columns : brand_id, brand_name, content, tags

Пример:

1 || Nike ||  shoes bags sports football soccer t-shirts track-pants
2 ||  GAP || wallets t-shirts jeans shoes perfumes

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

1 Ответ

0 голосов
/ 12 июня 2018

Я не понимаю, почему это неэффективное решение.

Это неэффективно, потому что вы должны извлекать и разбивать / искать эту строку для каждого запроса.

Когда вы делаете что-то вроде (как упомянуто в ваших ссылках) Three tables (one for storing all items, one for all tags, and one for the relation between the two), тогда вы можете использовать реальную силу реляционной базы данных, индекс .

Вместо того, чтобы разбивать каждую строку натег или набор тегов ... это уже сделано;Вы просто получаете те, которые хотите.Итак, если вы ищете «обувь», то он идет прямо туда (используя индекс, вероятно, log n или быстрее) и возвращает как Nike, так и GAP.Он будет делать это независимо от того, сколько у вас тегов, независимо от того, сколько у вас компаний.

С системой с 3 столами вы выполняете всю тяжелую работу заранее, а затем просто выполняете поиск.

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


Вопрос из комментария:

Можете ли вы привести примерСистема с 3 столами, нормализованная с атомарностью

Конечно.
Вы в основном просили Третью Нормальную Форму, которая является моей обычной целью.(Я признаю, что часто не делаю 3NF, потому что я оптимизирую; например, сохраняю почтовый индекс с адресами - если вы вне школы, это лучший выбор)

--Sample SQL stackoverflow.com/questions/50793168/database-design-for-tags-or-tagging/50818392
IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = N'ChrisC') 
BEGIN
 EXEC sys.sp_executesql N'CREATE SCHEMA [ChrisC] AUTHORIZATION [dbo]'
 IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[ChrisC].[Brands]') AND type in (N'U'))
     AND NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[ChrisC].[BrandTags]') AND type in (N'U'))
     AND NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[ChrisC].[Tags]') AND type in (N'U'))
 BEGIN
  CREATE TABLE [ChrisC].[Brands]([pkBrand] [int] IDENTITY(101,1) NOT NULL,[Name] [varchar](40) NULL) ON [PRIMARY]
  INSERT INTO [ChrisC].[Brands]([Name])VALUES('Nike'),('GAP')
  CREATE TABLE [ChrisC].[BrandTags]([pk] [int] IDENTITY(1,1) NOT NULL,[Brand] [int] NULL,[Tag] [int] NULL) ON [PRIMARY]
  INSERT INTO [ChrisC].[BrandTags]([Brand],[Tag])VALUES
    (101,201),(101,202),(101,203),(101,204),(101,205),(101,206),(101,207),
    (102,208),(102,209),(102,203),(102,207),(102,210)
  CREATE TABLE [ChrisC].[Tags]([pkTag] [int] IDENTITY(201,1) NOT NULL,[Tag] [varchar](40) NULL) ON [PRIMARY]
  INSERT INTO [ChrisC].[Tags]([Tag])VALUES
    ('bags'),('football'),('shoes'),('soccer'),('sports'),('track-pants'),('t-shirts'),('jeans'),('perfumes'),('wallets')
  SELECT b.[Name], t.Tag 
  FROM chrisc.Brands b 
  LEFT JOIN chrisc.BrandTags bt ON pkBrand = Brand
  LEFT JOIN chrisc.Tags t ON bt.Tag = t.pkTag
  WHERE b.[Name] = 'Nike'
  -- Stop execution here to see the tables with data
  DROP TABLE [ChrisC].[Brands]
  DROP TABLE [ChrisC].[BrandTags]
  DROP TABLE [ChrisC].[Tags]
 END
 IF  EXISTS (SELECT * FROM sys.schemas WHERE name = N'ChrisC') DROP SCHEMA [ChrisC]
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...