Разработка базы данных SQL для элемента с несколькими именами - PullRequest
1 голос
/ 18 марта 2019

Я создаю таблицу для dietary_supplement, где в добавке может быть много ингредиентов.

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

Например, у витамина В1 есть другие названия, такие как тиамин и тиамин.Аббревиатура BHA может обозначать как бутилированный гидроксианизол, так и бета-гидрокси кислоту (на самом деле это ингредиент для средств по уходу за кожей, но я в любом случае использую его, потому что это хороший пример).

Я также обеспокоен расстоянием и"-".Например, кто-то может записать витамин А без пробелов, а кто-то может написать витамин А. Кроме того, бета-гидроксикислота также может быть записана как β-гидроксикислота (с «-») или β-гидроксикислота (без «-»).

Я имею в виду 2 варианта)

1) поместите все имена одного ингредиента в столбец, используя точку с запятой для различения имен.например, бета-гидроксикислота, КНБК, -гидроксикислота, -гидроксикислота - это было бы легко, но я не уверен, что это разумный способ создания базы данных, когда мне нужно выполнить действия поиска и т. д.

2) создать таблицу для всех имен и связать ее с таблицей ингредиентов.-Это вариант, к которому я склонен, но мне интересно, есть ли лучшие способы сделать это.И нужно ли создавать отдельные строки для одних и тех же предметов с разницей в интервалах и "-"?

Ответы [ 3 ]

0 голосов
/ 18 марта 2019

Это может быть что-то вроде этого:

CREATE TABLE Ingredient (
      Id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
    , ImagePath VARCHAR(63)
    , Description TEXT
    -- other ingredient's non-name dependent properties
);

CREATE TABLE IngredientName (
      Id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
    , IngredientId INTEGER UNSIGNED NOT NULL
    , IsMain TINYINT(1) UNSIGNED NOT NULL DEFAULT 0
    , Name VARCHAR(63) NOT NULL
    , KEY IX_IngredientName_IngredientId_IsMain (IngredientId, IsMain)
    , UNIQUE KEY IX_IngredientName_IngredientId_Name (IngredientId, Name)
    , CONSTRAINT FK_IngredientName_IngredientId FOREIGN KEY (`IngredientId`) REFERENCES `Ingredient` (`Id`) ON DELETE CASCADE ON UPDATE CASCADE
);

Или вы можете добавить Ingredient.Name, которое будет основным именем, и убрать IngredientName.IsMain.

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

Есть и другие возможности.

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

P.S. Я считаю, что помещать разные имена в одно поле в качестве чего-то отдельного значения - плохая идея

0 голосов
/ 18 марта 2019

Создайте таблицу сопоставления 'name' для 'canonical_name' (или id). Это будет иметь строки, такие как

Thiamine   vitaminB1
thiamin    vitaminB1
vitaminB1  vitaminB1
B1         vitaminB1

Используя сопоставление, оканчивающееся на _ci, вам не нужно беспокоиться о капитализации.

При приеме данных для дополнения сначала найдите name, чтобы получить canonical_name, затем используйте последний в любой другой таблице (таблицах).

В этой таблице с двумя столбцами есть

PRIMARY KEY(canonical_name),
INDEX(name, canonical_name)

чтобы вы могли идти в любом направлении.

0 голосов
/ 18 марта 2019

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

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