powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Как добавить интернационализацию в EAV базу данных?
25 сообщений из 36, страница 1 из 2
Как добавить интернационализацию в EAV базу данных?
    #37713824
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги, добрый день!

Создаем базу данных на основании EAV-модели. Для сайта с различными каталогами различных объектов. Соответственно, EAV была выбрана, так как нужна гибкая модель данных, и чтобы был один и тот же компонент интерфейса для визуализации.

Так вот, сайт нужно сделать многоязычный. Поначалу для трех языков: русский, украинский, английский. Потом, возможно, и для других языков. Соответственно, объекты каталога должны отображаться на том языке, который пользователь выбрал для сайта.

Помогите, пожалуйста, спроектировать, как оптимально модифицировать EAV-модель, чтобы она поддерживала многоязычность?

Ниже привожу скрипт таблиц:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
/* Types of entity, for example - person, country, region */
create table EntityType(
    id varchar(32),
    name varchar(1024)
);

/* Attribute of entity, for example birthday of person */
create table Attribute(
    id varchar(32),
    entityTypeId varchar(32) REFERENCES EntityType(id), /* it is an attribute type*/
    name varchar(1024)
);

/* Entity of entity type. For example, concrete person Andrey Ivanov, or Country Germany */
create table Entity(
    id varchar(32),
    name varchar(1024),
    entityTypeId varchar(32) REFERENCES EntityType(id)
);

/* Real values of attributes. */
create table Parameter(
    entityId varchar(32) REFERENCES Entity(id),
    attributeId varchar(32) REFERENCES Attribute(id),
    varcharValue varchar(4096),
    datetimeValue timestamp,
    PRIMARY KEY (entityId, attributeId)
);



Что нужно: нужно чтобы как конкретные значения полей объекта (Parameter - должность конкретного человека, описание конкретного стула и т.д.) можно было отображать на апп-уровне в зависимости от языка, так и название объектов (Entity) в заголовке каталога, так и название атрибута (например: пол, возраст, описание).

Как корректней всего расширить модель данных для поддержки многоязычности?
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37713902
Фотография Программист-Любитель
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добавить справочник языков и из всех таблицы с варчами вынести варчары в дополнительные таблицы М:М с варчарами и айди языка.
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37713940
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Программист-ЛюбительДобавить справочник языков и из всех таблицы с варчами вынести варчары в дополнительные таблицы М:М с варчарами и айди языка.
Хм. То-есть, по одной таблице с варчарами на EntityType, Entity, Attribute и Parameter, или как? И почему связь M:M? У меня в модели данных строки если и будут повторятся, то крайне редко, и я не буду знать, как отсделить, что строка повторяется. Или что Вы имеете в виду?
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37713975
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 03/20/2012 05:24 PM, Vetal wrote:

> Помогите, пожалуйста, спроектировать, как оптимально модифицировать EAV-модель,
> чтобы она поддерживала многоязычность?

Надо добавить в PK таблицы, хранящей текстовые атрибуты, идентификатор языка.

У тебя -- в таблицу Parameter, но тут есть проблема, там у тебя хранятся
почему-то атрибуты всех типов (или у меня такое впечатление), тогда тебе
придётся завести ещё один тип языка -- language neutral -- и ставить его
в PK атрибутов нетекстовых типов.

Хотя я бы сделал отдельную таблицу для текстовых атрибутов.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37713989
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Хм. То-есть, по одной таблице с варчарами на EntityType, Entity, Attribute и
> Parameter, или как?

Только одна, LanguageParameter.

И почему связь M:M?

Потому что он неверно написал. 1:M должно быть.

Но если глядеть связь Attribute -- Language, то будет M:N.


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714059
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А я вот какое решение придумал:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
/* Types of entity, for example - person, country, region */
create table EntityType(
    id varchar(32),
    nameId varchar(1024) REFERENCES Resource(id)
);

/* Attribute of entity, for example birthday of person */
create table Attribute(
    id varchar(32),
    entityTypeId varchar(32) REFERENCES EntityType(id), /* it is an attribute type*/
    nameId varchar(1024) REFERENCES Resource(id)
);

/* Entity of entity type. For example, concrete person Andrey Ivanov, or Country Germany */
create table Entity(
    id varchar(32),
    nameId varchar(1024) REFERENCES Resource(id),
    entityTypeId varchar(32) REFERENCES EntityType(id)
);

/* Real values of attributes. */
create table Parameter(
    entityId varchar(32) REFERENCES Entity(id),
    attributeId varchar(32) REFERENCES Attribute(id),
    varcharValueId varchar(4096) REFERENCES Resource(id),
    datetimeValue timestamp,
    PRIMARY KEY (entityId, attributeId)
);

create table Language (
  langId varchar(32),
  name varchar (32)
)

create table Resource (
  resId varchar(32),
  langId varchar(32),
  value varchar(4096)
)
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714067
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ой, нажал на Опубликовать случайно без коммента, рука дрогнула :)

Идея какая: завести отдельную таблицу ресурсов, и туда ссылаться со всех других таблиц (поля varcharValueId в Parameter и nameId в остальных таблицах).

Что Вы думаете про такое решение? Или все же лучше создавать в таблице Parameter разные записи для разных языков?

И немного не понятно, как быть с таблицами Entity, EntityType и Attribute в Вашем случае. Ведь в них есть еще куча других нетекстовых полей, которые я не указал, придется их дублировать, а это уже денормализация получается. Как все же быть?
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714127
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Идея какая: завести отдельную таблицу ресурсов, и туда ссылаться со всех других
> таблиц (поля varcharValueId в Parameter и nameId в остальных таблицах).
>

Идея не очень , потому как тебе придётся лишнюю таблицу Parameter JOIN-ить
для каждого текстового атрибута.
Лучше бы просто отдельно хранить текстовые атрибуты, в отдельной таблице
для текстовых атрибутов.

create table TextParameter(
entityId varchar(32) REFERENCES Entity(id),
attributeId varchar(32) REFERENCES Attribute(id),
langId varchar(32),
value varchar(4096)
PRIMARY KEY (entityId, attributeId, langId)
);


> И немного не понятно, как быть с таблицами Entity, EntityType и Attribute в
> Вашем случае. Ведь в них есть еще куча других нетекстовых полей, которые я не
> указал, придется их дублировать, а это уже денормализация получается. Как все же
> быть?

Куда дублировать ? Не понял.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714141
Фотография Программист-Любитель
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имел в виду M:N.

Ваша таблица Parameter теряет поле Value
Таблица ParameterByLang хранит ключ таблицы Parameter, код языка и значение Value свое для каждого языка

Остальные таблицы тако же.
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714163
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что, лишний джойн сильно замедлит работу с базой?
И еще смущает то, что при этом решении для того, чтобы выбрать все параметры на клиенте (текстовые и нетекстовые), нужно сделать два запроса (типа как операция Union), а не один, хоть и с лишним джойном.

Что же все же дешевле выйдет?

MasterZiv> И немного не понятно, как быть с таблицами Entity, EntityType и Attribute в
> Вашем случае. Ведь в них есть еще куча других нетекстовых полей, которые я не
> указал, придется их дублировать, а это уже денормализация получается. Как все же
> быть?

Куда дублировать ? Не понял.

Ну, есть еще таблицы Entity, EntityType и Attribute, описывающие метаданные объектов, у них есть поле name.
К примеру, если представить себе каталог компьютеров, то страница компьютера на сайте будет выглядеть так:
Код: plaintext
1.
2.
Комьпьютер Онитрон 5
Процессор: Core2Duo 2.6Ггц
Тип охлаждения: жидкий
Здесь:
"Компьютер" - EntityType
"Онитрон 5" - Entity (конкретная модель компьютера)
"Процессор", "Тип охлаждения" - Attribute
"Core2Duo 2.6Ггц", "жидкий" - Parameter

Так вот, EntityType, Entity и Attribute тоже нужно интернационализировать. Только в них есть еще и другие поля. Например, в атрибуте есть его описание для администратора сайта, признак активности, параметры визуализации в интерфейсе, правила форматирования и т.п. Если мы будем дублировать эти записи для таблицы атрибутов, чтобы для каждого языка было свое значение, будет ненормализованность и дублирование остальных атрибутов.
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714167
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Программист-ЛюбительИмел в виду M:N.

Ваша таблица Parameter теряет поле Value
Таблица ParameterByLang хранит ключ таблицы Parameter, код языка и значение Value свое для каждого языка

Остальные таблицы тако же.
Ага, понял... А я как раз только что предложил, если Вы видели, создать таблицу Resource, где ресурсы со всех таблиц. Как Вы считаете, какое из наших решений лучше и почему?
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714187
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> А что, лишний джойн сильно замедлит работу с базой?

Нет, не сильно.

> Что же все же дешевле выйдет?

Не знаю, я бы вообще отдельно каждый тип атрибута хранил.

> Ну, есть еще таблицы Entity, EntityType и Attribute, описывающие метаданные
> объектов, у них есть поле name.

Ну, это всё остаётся как и было.


> Так вот, EntityType, Entity и Attribute тоже нужно интернационализировать.

Ааааа.

Ну сделай ещё по одной табличке дочерней, с языком.

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

Не, не надо дублировать. В отдельную таблицу надо только текстовые поля выносить.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714204
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv> Что же все же дешевле выйдет?
Не знаю, я бы вообще отдельно каждый тип атрибута хранил.


В разных таблицах? Зачем? Какое преимущество?

MasterZiv> Так вот, EntityType, Entity и Attribute тоже нужно интернационализировать.

Ааааа.

Ну сделай ещё по одной табличке дочерней, с языком.

А может, лучше сделать одну табличку на эти таблицы? И в каждой из этих таблиц просто заводить resourceId. Зачем плодить аж три таблицы, вроде так проще? А если вдруг появятся другие таблицы базы данных, которые тоже нужно будет интернационализировать, тоже по табличке на них создавать?
Или я все же заблуждаюсь?
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714258
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> В разных таблицах? Зачем? Какое преимущество?
>

Типизированное поле в таблице.


> А может, лучше сделать одну табличку на эти таблицы? И в каждой из этих таблиц
> просто заводить resourceId. Зачем плодить аж три таблицы, вроде так проще? А

Можно и так.



Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714291
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv
> В разных таблицах? Зачем? Какое преимущество?
>

Типизированное поле в таблице.
Так у меня ж тоже типизированные поля:
Вот полный текст таблицы:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create table Parameter(
    entityId varchar(32) REFERENCES Entity(id),
    attributeId varchar(32) REFERENCES Attribute(id),
    varcharValue varchar(4096),
    textValue text,
    integerValue integer,
    floatValue float,
    datetimeValue timestamp,
    booleanValue boolean,
    entityValue varchar(32) REFERENCES Entity(id), /* types for list options like computer, person, city , country and so on. */
    PRIMARY KEY (entityId, attributeId)
);


Чем Ваше решение лучше?

Немножко технических данных:
EntityType: сотни значений
Entity: сотни тысяч, возможно миллионы
Attribute: тысячи значений
Parameter: миллионы, возможно десятки миллионов значений

База данных: postgre9
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714309
oragraf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vetal,

не мудрствуй, языков не миллионы, добавь на каждый язык столбец для хранения значения на этом языке.
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714332
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oragrafVetal,

не мудрствуй, языков не миллионы, добавь на каждый язык столбец для хранения значения на этом языке.
Очень неудобно в таком случае писать слой работы с интернационализацией на апп-уровне. Придется для каждого языка хардкодить...
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714405
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 03/20/2012 08:16 PM, Vetal wrote:

> Чем Ваше решение лучше?

Не знаю, не думал. Но у тебя все поля значений будут NULL.
Если по таблице делать на тип значения , в таблицах будут все значения -- NOT NULL.

> Немножко технических данных:
> EntityType: сотни значений
> Entity: сотни тысяч, возможно миллионы
> Attribute: тысячи значений
> Parameter: миллионы, возможно десятки миллионов значений

Это всё равно. Миллион -- не миллиард. Ерунда.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714406
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 03/20/2012 08:26 PM, oragraf wrote:

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

Вот это -то как раз ни в коем случае нельзя делать.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714418
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivOn 03/20/2012 08:26 PM, oragraf wrote:

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

Вот это -то как раз ни в коем случае нельзя делать.

Интересно так же и Ваше мнение - почему?
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714422
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> create table Parameter(
> entityId varchar(32) REFERENCES Entity(id),
> attributeId varchar(32) REFERENCESAttribute(id),
> varcharValue varchar(4096),
> textValue text,
> integerValue integer,
> floatValuefloat,
> datetimeValuetimestamp,
> booleanValue boolean,
> entityValue varchar(32) REFERENCES Entity(id),/* types for list options like computer, person, city , country and so on. */
> PRIMARY KEY (entityId, attributeId)
> );
>
>
> Чем Ваше решение лучше?

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

Но!
Если делать такую таблицу, как у тебя, то если пойдёт в PK её LANGUAGE, то
ВСЕ атрибуты будут иметь возможность иметь разные языки, а для атрибутов
других типов это не нужно. (это не очень страшно, главное правилами какими-то
запретить вставку таких данных).

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

Кроме этого, наверняка тебе захочется создать индексы на разные xxValue,
чтобы по ним можно было бы искать. Это уже тонкая материя, тут уже надо знать
о конкретике СУБД в реализации, но всё же, для каждого xxxVal в таблице
будет N записей (всего атрибутов), из них n будет этого значения,
а N-n будет NULL. Это может портить статистику и селективность. А может и не
портить.

В общем, штука сложная.



Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714423
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Интересно так же и Ваше мнение - почему?

Нарушение 1 НФ.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714573
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivИ почему связь M:M?

Потому что он неверно написал. 1:M должно быть.

Но если глядеть связь Attribute -- Language, то будет M:N.
Я вот подумал. У меня ресурс - уникальное значение. Один ресурс не может быть к разным Entity или Parameter. Поэтому зависимость получается M:1.

Поэтому, на примере Entity, я вижу следующее решение:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create table Entity(
    id varchar(32),
    entityTypeId varchar(32) REFERENCES EntityType(id),
    -- другие поля
);

create table EntityResource (
  resId varchar(32) Primary Key,
  langId varchar(32),
  value varchar(4096)
  EntityId varchar(32) REFERENCES Entity(id)
  UNIQUE INDEX (resId, langId)
)



Иначе, если я сделаю первичным ключом resId и langId, тогда эти оба поля придется перетащить в Entity, что недопустимо, так как тогда для разных языков придется дублировать поля Entity.

Тогда, чтобы вытащить из Entity его имя, нужно сделать джойн Entity с EntityResource по EntityResource.EntityId, и добавить условие фильтрации langId = <id языка>.

Возникает вопрос: как лучше сделать для всех таблиц. К примеру, чтобы сделать интернационализацию для Entity и Attribute, есть два варианта:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
create table Entity(
    id varchar(32),
    nameId varchar(1024) REFERENCES Resource(id),
    entityTypeId varchar(32) REFERENCES EntityType(id),
	-- other fields
);

create table Attribute(
    id varchar(32),
    entityTypeId varchar(32) REFERENCES EntityType(id),
	-- other fields
);

create table Resource (
  resId varchar(32) Primary Key,
  langId varchar(32),
  value varchar(4096)
  EntityId varchar(32) REFERENCES Entity(id)
  AttributeId varchar(32) REFERENCES Attribute(id)
  UNIQUE INDEX (resId, langId)
)



или:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
create table Entity(
    id varchar(32),
    nameId varchar(1024) REFERENCES Resource(id),
    entityTypeId varchar(32) REFERENCES EntityType(id),
	-- other fields
);

create table Attribute(
    id varchar(32),
    entityTypeId varchar(32) REFERENCES EntityType(id),
	-- other fields
);

create table EntityResource (
  resId varchar(32) Primary Key,
  langId varchar(32),
  value varchar(4096)
  EntityId varchar(32) REFERENCES Entity(id)
  UNIQUE INDEX (resId, langId)
)

create table AttributeResource (
  resId varchar(32) Primary Key,
  langId varchar(32),
  value varchar(4096)
  AttributeId varchar(32) REFERENCES Attribute(id)
  UNIQUE INDEX (resId, langId)
)



Как лучше сделать, как считаете?
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714629
oragraf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivOn 03/20/2012 08:26 PM, oragraf wrote:

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

Вот это -то как раз ни в коем случае нельзя делать.

Ок, у меня фамилия - 1 штука, имя - 1 штука, отчество - 1 штука. Почему я не могу сделать 3 столбца (lastname, firstname, middlename) в таблице клиентов?
...
Рейтинг: 0 / 0
Как добавить интернационализацию в EAV базу данных?
    #37714669
oragraf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VetalОчень неудобно в таком случае писать слой работы с интернационализацией на апп-уровне. Придется для каждого языка хардкодить...Это очень надуманная причина. Многое решается генерацией кода.
ЗЫ. Я согласен с тем, что количество языков будет фиксировано на этапе проектирования.
...
Рейтинг: 0 / 0
25 сообщений из 36, страница 1 из 2
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Как добавить интернационализацию в EAV базу данных?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]