Дизайн базы данных для тегов или тегов

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

У каждого элемента есть несколько тегов. Я прочитал несколько ответов о том, как это сделать:

  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

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

Определите эффективный. Удобно для письма? эффективен для чтения? эффективен для обслуживания кода?

Nick.McDermaid 21.06.2018 06:06

Эффективен для сопровождения кода и прост в использовании

Shivansh Jagga 21.06.2018 19:11

Что ж, IMHO, хорошее обслуживание кода = простой код = не используйте сложный код для разделения и добавления строк в одну строку. Просто сделай простую вставку

Nick.McDermaid 22.06.2018 05:59
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
6
3
4 796
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

I don't understand why this is not an efficient solution.

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

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

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

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

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


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

Can you give an example of a 3 table system that is normalized with atomicity

Конечно.
По сути, вы попросили третью нормальную форму, что является моей обычной целью. (Признаюсь, я часто не делаю 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

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

Shivansh Jagga 13.06.2018 19:26

Сделанный. Дайте мне знать, если у вас есть вопросы (я использовал настраиваемую схему, которая, надеюсь, не сбивает с толку)

J. Chris Compton 21.06.2018 19:56

Другие вопросы по теме