powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Организация БД мультиязычного сайта
60 сообщений из 60, показаны все 3 страниц
Организация БД мультиязычного сайта
    #38431250
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, товарищи!

Попытаюсь максимально доходчиво объяснить свою проблему с помощью простых примеров «на пальцах».

Итак, например, есть таблица пользователей:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create table dbo.User(
    
    -- ID пользователя.
    int id,

    -- Имя пользователя.
    varchar name,

    -- ID города пользователя.
    int cityId foreign key references dbo.City(id)
);



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

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
create table dbo.City(

    -- ID города.
    id int,

    -- Имя города.
    varchar name
);



Есть простой запрос с JOIN'ом, который излекает все данные пользователя, заменяя идентификатор города на название города.

Код: sql
1.
select * from dbo.User as User left join dbo.City as City on User.cityId = City.id where id = 1;



А теперь представим эту базу данных в контексте работающего сайта. И не просто сайта, а сайта мультиязычного, где (тут внимание!) : таблица dbo.User одна в неизменном виде, а вот таблиц dbo.City должно быть несколько: одна версия с русскими названиями городов, вторая, пускай, с английскими названиями тех же городов с теми же идентификаторами. Это нужно для того, чтобы можно было извлекать данные пользователя как с русскими названиями городов, так и с английскими. ПРИЧЁМ, dbo.City на русском будет находится в одной базе данных, а dbo.City на английском — в другой базе данных; при этом dbo.User должна быть общей для обоих баз данных — как это реализовать?

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

2) Второй вариант, держать в базе данных 2 таблицы городов: dbo.CityRUS и dbo.CityENG и уже, в зависимости, например от какого-то передаваемого в запрос параметра с идентификатором языка, выполнять переключение в дуже SWITCH:

Код: c#
1.
2.
3.
4.
5.
6.
7.
SWITCH langId:
    case "RUS":
      select ... join on dbo.CityRUS.id;
      break;
    case "ENG"
      select ... join on dbo.CityENG.id;
      break;



Но, я считаю, что это извращение.

3) Вариант — сделать так, чтобы в таблице городов хранились и русские и английские названия в разных колонках — не вариант, потому, что БД желательно разместить на разных серваках — из-за неоднородности нагрузки исходящей от клиентов, которые используют английские и русские названия городов.

Может есть какое-то просто и быстрое решение, до которого я просто не могу додуматься?

Также, сразу хочу отметить, что я против использования динамических SQL-запросов (ну, естественно, кроме ситуаций, где без них никак) — т.е., только хранимые процедуры.

Спасибо!

Роман.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431294
Злой Бобр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenko,

Вариант 3 будет самым быстрым. Кроме того мультиязычность никак не влияет на количество БД. Как правило все хранится в одной БД, либо в таблицах _en _ru ..., либо в столбцах таблиц соответственно.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431303
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Злой Бобрroman_lenko,

Вариант 3 будет самым быстрым. Кроме того мультиязычность никак не влияет на количество БД. Как правило все хранится в одной БД, либо в таблицах _en _ru ..., либо в столбцах таблиц соответственно.

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

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create table dbo.City(

    -- ID города.
    id int,

    -- Имя города (русское).
    varchar nameRUS,

    -- Имя города (английское).
    varchar nameENG
);



А извлекать методом, по типу того, как я описал в примере?:

Код: c#
1.
2.
3.
4.
5.
6.
7.
SWITCH @langId:
    case "RUS":
      select ... join on dbo.CityRUS.id;
      break;
    case "ENG"
      select ... join on dbo.CityENG.id;
      break;
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431307
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ошибся:

Код: c#
1.
2.
3.
4.
5.
6.
7.
SWITCH @langId:
    case "RUS":
      select City.nameRUS ... join on dbo.City.id;
      break;
    case "ENG"
      select City.nameENG ... join on dbo.City.id;
      break;
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431319
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обычно это выглядит как единая таблица языкозависимых названий, типа
ObjectID
ObjectTypeID /* если разноязычные названия нудны не только для городов, но и для других обьектов*/
Language
Literal.

таким образом, у Вас единая таблица City c одной записью на каждый город, и к каждому городу несколько дочерних записей в таблице названий, по одной на каждый язык.
Ссылочная целостность, правда, требует дополнительных ухищрений- но тоже ничего нерешаемого нет.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431335
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenkoдержать 2 копии таблицы dbo.User в обоих базах данных, но таким образом
мне необходимо будет данные в 2-х таблицах синхронизировать, а это значит нужно писать
систему синхронизации, чего делать мне не хочется.
А использовать готовые механизмы репликации не позволяет что?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431340
Злой Бобр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenko,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create table dbo.City(

    -- ID города.
    id int,

    -- Имя города (русское).
    varchar name_RUS,

    -- Имя города (английское).
    varchar name_ENG
);



Да, извлекать примерно так же. Единственное пользователь на сайте сам выбирает язык. Вот выбранное значение и необходимо будет подставить. При этом в таблице юзеров также добавьте язык по умолчанию. Это на случай если значение в столбце выбранного языка будет пустое то подставить значение из таблицы юзеров.
Соответственно и запрос у вас изменится.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431343
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кот МатроскинОбычно это выглядит как единая таблица языкозависимых названий, типа
ObjectID
ObjectTypeID /* если разноязычные названия нудны не только для городов, но и для других обьектов*/
Language
Literal.

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

Я не понял :) Слишком абстрактно.

Т.е., вы имеете ввиду, что-то типа такого:

create table dbo.City(

-- ID города.
id int,

-- Имя города.
varchar name,

-- Ссылка на другой город.
reference id
);

-- Например, это будет один и тот же город:
insert into dbo.City values(1, 'Санкт-Петербург', NULL);
insert into dbo.City values(NULL, 'St. Petersbourg', 1);

Т.е., город с именем St. Petersbourg — ссылается на город 'Санкт-Петербург' — так?
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431346
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Злой БобрДа, извлекать примерно так же. Единственное пользователь на сайте сам выбирает язык. Вот выбранное значение и необходимо будет подставить. При этом в таблице юзеров также добавьте язык по умолчанию. Это на случай если значение в столбце выбранного языка будет пустое то подставить значение из таблицы юзеров.
Соответственно и запрос у вас изменится.

Извращенно, но что поделаешь. Спасибо!
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431355
Злой Бобр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кот Матроскин,

Этот вариант автору неподойдет. Во первых запрос отработает медленнее. Во вторых - зачем хранить все в одной огромной таблице (EAV)? Да, с одной стороны это удобно. Но с другой - мы незнаем объемов таблиц и полей БД автора. Множим примерно на 5 языков и понимаем что занимаемся ерундой.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431360
Злой Бобр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenko,

Да ничего извращенного. Посмотрите готовые шаблоны cms, там все это уже реализовано.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431362
LSV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если список языков - константа, то можно добавить отдельное поле для конкретного языка.
Если нет, то в таблицах делать составной ключ - код+язык.

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

Отдельные таблицы для разных языков - тупиковое решение.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431363
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Злой БобрНо с другой - мы незнаем объемов таблиц и полей БД автора. Множим примерно на 5 языков и понимаем что занимаемся ерундой.

По объёмам данных — города 27 стран мира, переведённые где-то на 10 языков — т.е., реально много.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431369
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenko,

Нет, не совсем. Так как Вы предлагаете, имеет смысл делать, если в табоице city единственное информационное поле - name.
А если там еще, например, координаты, число жителей, принадлежность к стране и т.п. - какой смысл дублировать эти данные для 'Санкт-Петербург' и 'St. Petersbourg'?
я предлагал следующее

Код: sql
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.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
create table dbo.City(

-- ID города.
id              int,
IDCountry   int,
CitizenCount int,
...
)

create table dbo.Literal
(
ObjectID int
ObjectTypeID  int /* если разноязычные названия нужны не только для городов, но и для других обьектов*/
Language  char(2)
Literal       nvarchar(1000)
)

/* всталваяем запись о городе 'Санкт-Петербург' */
Insert into City ( ID, .....)
  values (1, ....)

/* вставлаяем запись о городе 'Москва' */
Insert into City ( ID, .....)
  values (2, ....)



Insert into dbo.Literal ( ObjectIDID, ObjectTypeID, Language,Literal  )
  values (1,  /* ID нашего города*/
             12, /* Константа, обоазначающая что ссылка относится к городам*/
             'RU',
             'Санкт-Петербург' 
)

Insert into dbo.Literal ( ObjectIDID, ObjectTypeID, Language,Literal  )
  values (1,  /* ID нашего города*/
             12, /* Константа, обоазначающая что ссылка относится к городам*/
             'EN',
             'St. Petersbourg')

Insert into dbo.Literal ( ObjectIDID, ObjectTypeID, Language,Literal  )
  values (2,  /* ID нашего города*/
             12, /* Константа, обоазначающая что ссылка относится к городам*/
             'EN',
             'Moscow')

Insert into dbo.Literal ( ObjectIDID, ObjectTypeID, Language,Literal  )
  values (2,  /* ID нашего города*/
             12, /* Константа, обоазначающая что ссылка относится к городам*/
             'RU',
             'Москва')
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431381
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ого! Ну, примерно, понял. Из полей у меня только идентификатор города и название города — больше ничего.

А как тогда извлекать данные по вашему примеру? (с JOIN'ом).
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431388
Злой Бобр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кот Матроскин,

Эм... А разве кто-то числовые поля разделяет по языковому признаку? Непоймите меня неправильно, просто я такой бред слышу первый раз. Число оно и в африке число. Естественно кроме специфических направлений (например археология), но даже там нет предлагаемого разделения по языкам.
Вы наверное долго с TecDoc возились. Там как раз то что вы предлагаете. Но лично я считаю что ребята пошли не тем путем.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431393
Гхостик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
roman_lenkoПо объёмам данных — города 27 стран мира, переведённые где-то на 10 языков — т.е., реально много.С точки зрения базы, это не очень много.

2 Кот Матроскин:
А если в таблице есть более одного поля, подлежащего переводу?
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431440
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ГхостикА если в таблице есть более одного поля, подлежащего переводу?

1) Выделяется сущность "текст"
2) Выделяется сущность "переводы текста"
3) Создаются соответствующие таблицы, вторичные ключи и вьюхи.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431548
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Злой БобрВо вторых - зачем хранить все в одной огромной таблице (EAV)? Но с другой - мы незнаем объемов таблиц и полей БД автора. Множим примерно на 5 языков и понимаем что занимаемся ерундой
к EAV это не имеет вообще никакого отношения.
Вариант, который Вам нравится (с несколькими полями одной записи) чрезвычайно сложно переживет добавление еще одного языка - придется переписывать кучу кода.
Опять же возьмем случай Гхостика (N полей, требующих перевода) - придется создать N * M (M -кол-во возможных переводов) полей. "Понимаем, что занимаемся ерундой" (с)


Злой БобрКот Матроскин,

Эм... А разве кто-то числовые поля разделяет по языковому признаку?

Какие числовые поля?

Гхостик А если в таблице есть более одного поля, подлежащего переводу?

В таблицу Literal добавится поле TypeField.

roman_lenko
А как тогда извлекать данные по вашему примеру? (с JOIN'ом).


Код: sql
1.
2.
3.
4.
5.
6.
7.
from dbo.User as User 
       left join dbo.City as City 
       on User.cityId = City.id
       left join dbo.Literal as L
       on L.ObjectID = City.ID and
           l.ObjectTypeID = 12 and /* константа,  соответствующая городам*/
           l.Language = @CurrentLanguage /* текущий язык, для которого мы извлекаем данные */
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431644
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем большое спасибо за ответы — мне, если честно, теперь все варианты нравятся (хотя раньше ни один особо не нравился:) Теперь мне нужно будет подумать и выбрать конкретно применительно к моему сайту.

Единственная просьба еще к Коту Матроскину : ваш пример для меня очень сложен, я его понимаю, но боюсь, что, или понимаю только на половину, или понимаю не совсем правильно. Прошу вас объяснить максимально просто на основе моей таблицы городов (смотрите — у меня есть PRIMARY KEY для поля City.id — ваша схема, как я понимаю, PRIMARY KEY не учитывала, т.к., вы в примере вставляли два города с одинаковым идентификатором, но названиями на разном языке).

Таблица городов (в ней больше нет НИКАКИХ полей, кроме указанных):

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create table dbo.City(

    -- ID города.
    id int not null primary key,

    -- Имя города.
    varchar(64) name not null,

    -- Идентификатор языка.
    languageId char(2) not null
);



А вот указаный вами запрос для извлечения данных — я его переписал:

Код: sql
1.
2.
3.
4.
from dbo.User as User 
    left join dbo.City as City on User.cityId = City.id
    left join dbo.Literal as L on L.ObjectID = City.ID
    L.languageId = @CurrentLanguage;



Правильно? — видимо, нет — не понимаю, что это за таблица dbo.Literal — зачем она нужна?
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431740
Sgt.Pepper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenkoТаблица городов (в ней больше нет НИКАКИХ полей, кроме указанных):

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create table dbo.City(

    -- ID города.
    id int not null primary key,

    -- Имя города.
    varchar(64) name not null,

    -- Идентификатор языка.
    languageId char(2) not null
);



[..]

Правильно? — видимо, нет — не понимаю, что это за таблица dbo.Literal — зачем она нужна?Матроскин предлагает из Вашей таблицы City сделать две: собственно ГОРОДА и НАПИСАНИЯ_ГОРОДОВ.
И это правильно.

Если в Вашей City убрать languageId, то она будет ГОРОДА,
а если в ней же с ID_Города убрать 'primary key' и ввести дополнительно PK на ID_Написание, то она превратится в Literal
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
create table dbo.City(

    -- ID города.
    id int not null primary key,

    -- Имя города.
    varchar(64) name not null,
);

create table dbo.Literal(

    -- ID написания.
    id int not null primary key,

    -- ID города.
    id_city int not null,

    -- Не Имя, а Написание города.
    varchar(64) name not null,

    -- Идентификатор языка.
    languageId char(2) not null
);




Как упоминалось, неприятностей стОит ожидать при поддержании целостности, например, следует задаться вопросом: может ли быть город в City и не иметь ни одного написания в Literal?
Какие бизнес правила нарушаются, если City будет не таблицей, а вьюхой из Literal, с 'languageId = @CurrentLanguage'
Ну и тому подобные...
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431751
Гхостик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Зачем язык в справочнике городов? Я бы сделал так (синтаксис оракловый):

Код: 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.
-- города
create table city (
  id integer not null primary key,
  name varchar2(100) not null -- значение по умолчанию
);

-- тексты к переводу
create table texts (
  id integer not null primary key,
  table_name varchar2(30) not null check (table_name = upper(table_name)),
  field_name varchar2(30) not null check (field_name = upper(field_name)),
  constraint unq_texts_tf unique (table_name, field_name)
);

-- переведенные тексты
create table text_trans (
  object_id integer not null,
  text_id integer not null references texts(id),
  lang char(2) not null,
  text varchar2(4000),
  primary key (object_id, text_id, lang)
);

-- для примера
insert into texts (id, table_name, field_name) values (1, 'CITY', 'NAME');

-- переведенные города 
create view v_city (id, name) as
select c.id, coalesce(t.text, c.name) name
from city c
left join text_trans t on
  t.object_id = c.id and 
  t.text_id = 1 and 
  t.lang = ptrans.get_current_lang and -- выбранный язык текущей сессии
  1=1
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431802
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> create table dbo.City()
> create table dbo.Literal()

Всё бы хорошо, Кот Матроскин, но вам понадобятся эквиваленты не только названий, но и топонимов. Иногда прямое соответствие для разных языков существует, иногда нет. Что намерены делать?
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431815
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sgt.Pepper, я немного подредактировал то, что вы написали: я добавил FOREIGN KEY для dbo.Literal.id_city — это правильно? Я вот теперь не понимаю зачем мне нужно ID написания, если у меня, например, уже есть languageId?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
create table dbo.City(

    -- ID города.
    id int not null primary key,

    -- Имя города.
    varchar(64) name not null,
);

create table dbo.Literal(

    -- ID написания.
    id int not null primary key,

    -- ID города.
    id_city int not null foreign key references dbo.City(id),

    -- Не Имя, а Написание города.
    varchar(64) name not null,

    -- Идентификатор языка.
    languageId char(2) not null
);



Короче, видимо, в рамках форума мне это понять не получится :/

Гхостик, извиняюсь, но я не понимаю вашего примера. Тут уже «переводы» пошли, «тексты» — помоему, это из другой области, или я вы предлагаете принципиально другую реализацию.

guest_20040621, вот только топонимов еще не хватало :) У меня не настолько сложная база.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431874
Фотография lLocust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenko,

А вам и не нужно ID написания, смело удаляйте. А primary key составной на id_city и languageId.

Блин... и постарайтесь придерживаться единых правил: или id_city и id_language или cityId и languageId. Сами же потом путаться будете )

P.s. и еще Кот Матроскин предлагал сделать одну таблицу для всех переводов (поэтому добавил поле ObjectTypeID - обозначающее что за перевод тут хранится). Вы это поле убрали и фактически сделали эту таблицу только для перевода городов. Вот и назовите ее как-нибудь CityTranslate, а не Literal (а то потом другому разработчику будет сложно понять что вы хотели).
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38431883
Фотография lLocust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenkoГхостик, извиняюсь, но я не понимаю вашего примера. Тут уже «переводы» пошли, «тексты» — помоему, это из другой области, или я вы предлагаете принципиально другую реализацию.

То же самое, что и предложил Кот Матроскин просто:
1) в других терминах
2) с дополнительной таблицей для определения типов сущностей
3) Более удобный с точки зрения дальнейшего сопровождения кода (другой программист сразу поймет как это все работает)
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432012
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
guest_20040621> create table dbo.City()
> create table dbo.Literal()

Всё бы хорошо, Кот Матроскин, но вам понадобятся эквиваленты не только названий, но и топонимов. Иногда прямое соответствие для разных языков существует, иногда нет. Что намерены делать?
Не совсем понял фразу "не только названий, но и топонимов". Можете привести пример?
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432021
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> Можете привести пример?

Город, село, деревня, станица, рабочий посёлок, хутор и пр. Уровень выше (не топонимы, но сходная задача): край, область и пр.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432054
Sgt.Pepper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenkoSgt.Pepper, я немного подредактировал то, что вы написали: я добавил FOREIGN KEY для dbo.Literal.id_city — это правильно?Разумеется. Я FK не описал, думал - само собой понятно...
roman_lenkoЯ вот теперь не понимаю зачем мне нужно ID написания, если у меня, например, уже есть languageId?С точки зрения строгой теории - не нужен, в качестве PK вполне может выступить id_city+id_language. Просто для меня правило - для каждой таблицы создавать суррогатный ключ...

Лучше расскажите как предполагается работать с этими multilanguage-городами.
У Вас есть что-то типа КЛАДР для разных стран на разных языках?
Или Вы предполагаете иметь специалистов, которые для тысяч, скажем, российских городов будут вводить эквивалент на суахили?..
Проблема ли то, что некий город для выбранного языка не имеет в базе "перевода" и, как следствие, для пользователей, выбравших этот язык, не отобразится?
Т.е., другими словами, для каждого языка будет свой набор городов...
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432083
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ребят, спасибо — столько ответов, прямо не ожидал.

lLocust А вам и не нужно ID написания, смело удаляйте. А primary key составной на id_city и languageId.

Блин... и постарайтесь придерживаться единых правил: или id_city и id_language или cityId и languageId. Сами же потом путаться будете )

P.s. и еще Кот Матроскин предлагал сделать одну таблицу для всех переводов (поэтому добавил поле ObjectTypeID - обозначающее что за перевод тут хранится). Вы это поле убрали и фактически сделали эту таблицу только для перевода городов. Вот и назовите ее как-нибудь CityTranslate, а не Literal (а то потом другому разработчику будет сложно понять что вы хотели).


Простите-с, а как составной Primary Key определять? — разве кластеризированный индекс можно объявлять для более чем одного поля таблицы (я использую Microsoft SQL Server).

Про написание — то понятно; автор так написал — я и скопировал.

И наконец-то понял, что это за Literal такой! Я же не знал, что по задумке Матроскина это одна таблица для всех переводов. Нет — мне только для городов нужно.

Sgt.PepperРазумеется. Я FK не описал, думал - само собой понятно...

Ну... нет :) Какраз такие детали для меня и составляют «паззл» целиком — лучше дважды переспросить.

Sgt.PepperЛучше расскажите как предполагается работать с этими multilanguage-городами.
У Вас есть что-то типа КЛАДР для разных стран на разных языках?
Или Вы предполагаете иметь специалистов, которые для тысяч, скажем, российских городов будут вводить эквивалент на суахили?..

Да нет — всё намного проще. У меня уже есть готовый проект — сайт поиска музыкантов . Но он пока только на русском языке, а я хочу перевести его на другие языки, т.к., он сейчас для 3-х стран действует: Украина, Россия, Беларусь. Вот, например, есть объявление о поиске музыканта , в нём человек, при регистрации, выбрал себе город «киев, украина» (сущность «город», City ) и инструмент «гитара/электрогитара» (сущность «инструмент», Tool ), так вот я хочу, чтобы, например, в украинской версии сайта у музыканта было написано «київ, україна» и «гітара/электрогітара» соответственно — для этого вся эта канитель с городами и началась — мне нужно перевести все доступные в базе данных города на другие языки, чтобы они показывались на странице музыканта. Идея такова.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432099
Злой Бобр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenko,

Вы только незабывайте что имена собственные непереводятся.
Ну и "электрогітара" - нет такого слова в украинском.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432108
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Злой Бобрroman_lenko,
Вы только незабывайте что имена собственные непереводятся.
Ну и "электрогітара" - нет такого слова в украинском.

Ну, города ведь пишутся по разному, например, киев = київ. Да — гитару неправильно написал — електрогітара.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432113
Злой Бобр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenko,

Не все города. Поэтому и предупредил, т.к. сам наступал на эти грабли во времена "студенчества".
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432122
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Буду иметь ввиду — спасибо. Все равно буду в Википедию подсматривать — там точно не ошибусь.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432202
Гхостик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
roman_lenkoодна таблица для всех переводов. Нет — мне только для городов нужно.



roman_lenkoв украинской версии сайта у музыканта было написано «київ, україна» и «гітара/электрогітара» соответственно

Вижу несоответствие.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432435
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
guest_20040621> Можете привести пример?

Город, село, деревня, станица, рабочий посёлок, хутор и пр. Уровень выше (не топонимы, но сходная задача): край, область и пр.
Не представляю себе задачу, чтобы точная работа с этим была важна при переводах . Ну назовут при переводе и деревню и село village - какая разница? Даже если окажется, что мы два разных обьекта "село Ивантеевка" и "деревня Ивантеевка" назвали одинаково Ivanteevka village - ну и черт бы с ним, мы же не почтовые адреса печатаем.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432478
Sgt.Pepper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кот Матроскин,
Есть ли необходимость в существовании наименования города в City?
Что там должно стоять для Киева, Москвы и Рима, учитывая что русские, украинские и итальянские названия всех трех городов есть в Literal?..
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432489
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sgt.PepperЕсть ли необходимость в существовании наименования города в City?

Есть, Default Value. Ведь соответствующей записи в Literal может не быть, тогда можно IsNull(Literal.Name, City.Name)
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432491
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sgt.PepperЕсть ли необходимость в существовании наименования города в City
В приведенной мной схеме - нет, конечно.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432506
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> Не представляю себе задачу, чтобы точная работа с этим была важна

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

> какая разница?

Неправильно идентифицированный населённый пункт = неправильно решённая задача. Источников геморроя два: топонимы и правила перевода. Даже однозначных общепринятых правил транслитерации не существует, не говоря о прочем.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432719
Sgt.Pepper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79Есть, Default Value. Ведь соответствующей записи в Literal может не быть, тогда можно IsNull(Literal.Name, City.Name)И что будет для Рима default value?
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432760
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot guest_20040621
Неправильно идентифицированный населённый пункт = неправильно решённая задача.
...
Даже однозначных общепринятых правил транслитерации не существует, не говоря о прочем.[/quot]
Совершенно верно. Поэтому пытаться что-то однозначно идентифицировать по переводу - имхо совершенно безнадежное дело. Насколько я знаю, если написать на конверте по русски " Великобритания, Лондон, Бейкер-стрит 221B" - письмо не дойдет
никуда по определению.
Топонимы имхо важны для другого - понимать, что для обозначения столицы РФ "город Москва", "г Москва" и "г. Москва" - это правильное написание, а "с. Москва" - какая-то фигня.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432842
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> идентифицировать по переводу - имхо совершенно безнадежное дело

Не уверен. Но это не совсем перевод, это эквивалент (топоним + название) с кучей правил и исключений.

> Топонимы имхо важны для другого

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

Топонимы могут нести семантическую нагрузку, которую глупо терять. ОК, не важно, в конце концов, для чего их можно использовать. Не хотите модифицировать предложенный вами вариант?
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432924
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
guest_20040621Топонимы могут нести семантическую нагрузку, которую глупо терять. ОК, не важно, в конце концов, для чего их можно использовать. Не хотите модифицировать предложенный вами вариант?
Мне не до конца понятна задача - что мы хотим от структуры?

Ну например, добавить таблицу "Типы населенных пунктов" (соответственно, в City внешний ключ на нее), вбить в нее все национальные деления (т.е. там будут, в частности, 3 разные записи "Село", "Деревня", "Village"), иметь в этой таблице поле "Страна, в которой принято данное деление" (внешний ключ на таблицу стран), в моей таблице Literal хранить переводы типов точно также как переводы городов.
Т.е. для типа "Деревня" будут записи в Literal
RU Деревня EN Village
для "Село"
RU Село EN Village
для "Village"
EN Village RU Деревня

Такую структуру переводов несложно дозаполнить автоматически, при этом оставив у эксперта-человека возможность вмешаться и поменять данные так, как он считает нужным.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432979
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sgt.PepperArm79Есть, Default Value. Ведь соответствующей записи в Literal может не быть, тогда можно IsNull(Literal.Name, City.Name)И что будет для Рима default value?

Какой язык первичный, такой и писать. Если сайт ориентирован в первую очередь на Запад, то английский
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38432999
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> что мы хотим от структуры?

Вариант, который устроит нас в неизменном виде для 99% случаев. Т. е. почтовая адресация, картография, логистика и пр. в него должны уложиться.

> добавить таблицу "Типы населенных пунктов"

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

> для типа "Деревня" будут записи в Literal

Не смущает, что у вас разные результаты для разных направлений преобразования?
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433295
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
guest_20040621> для типа "Деревня" будут записи в Literal

Не смущает, что у вас разные результаты для разных направлений преобразования?

Совершенно нет.
1. Направление преобразования всегда одно - перевод с родного по отношению к топониму языка на иностранный. Я уже говорил,
что считаю задачу автоматического перевода "город Лондон" на английский и на основании перевода идентификации города - неразумной.
2. Даже если отвлечься от 1., для переводов это вообще нормальная ситуация. Если Гугл транслейтом перевести текст с русского на английский и потом обратно на русский - результат тоже будет отличаться от первоначального.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433369
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> Если Гугл транслейтом перевести текст

Мы обсуждаем имена собственные, и как раз с ними у google есть проблемы. ОК, давайте на этом закончим. Спасибо за изложение вашей точки зрения.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433423
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenko таблица dbo.User одна в неизменном виде, а вот таблиц dbo.City должно быть несколько: одна версия с русскими названиями городов, вторая, пускай, с английскими названиями тех же городов с теми же идентификаторами. Это нужно для того, чтобы можно было извлекать данные пользователя как с русскими названиями городов, так и с английскими. ПРИЧЁМ, dbo.City на русском будет находится в одной базе данных, а dbo.City на английском — в другой базе данных; при этом dbo.User должна быть общей для обоих баз данных — как это реализовать?

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

2) Второй вариант, держать в базе данных 2 таблицы городов: dbo.CityRUS и dbo.CityENG и уже, в зависимости, например от какого-то передаваемого в запрос параметра с идентификатором языка, выполнять переключение в дуже SWITCH:

Код: c#
1.
2.
3.
4.
5.
6.
7.
SWITCH langId:
    case "RUS":
      select ... join on dbo.CityRUS.id;
      break;
    case "ENG"
      select ... join on dbo.CityENG.id;
      break;



Но, я считаю, что это извращение.


Правильно считаешь.
Никаких двух баз, никаких двух таблиц быть не должно.


автор3) Вариант — сделать так, чтобы в таблице городов хранились и русские и английские названия в разных колонках — не вариант, потому, что БД желательно разместить на разных серваках — из-за неоднородности нагрузки исходящей от клиентов, которые используют английские и русские названия городов.


Ты прав, не вариант.

Решается достаточно просто , в общем, есть два варианта.

Либо к каждой таблице, где храняться переводимые данные, ты делаешь таблицу с суффиксом (или префиксом) , например, "_INT"
или "_TRANS", где таблица состоит из:

полей PK изначальной таблицы

добавленного в PK идентификатора языка (лучше в виде текстовой константы -- кода языка типа 'RU' 'EN' и т.д.)

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

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

Использование очевидно:

Код: sql
1.
2.
3.
4.
select 
  c.city_id, coalesce( ct.name, c.name ) as name
from CITY c
left join CITY_TRANS ct on c.city_id = ct.city_id and ct.lang = 'RU'




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

PK -- ид сущности, ид атрибута сущности, ид экземпляра сущности, ид языка. Атрибут один -- значение атрибута на данном языке.

Запросы аналогичны, только ещё константами будут задаваться ид сущности и ид атрибута сущности.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433424
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenkoНо, я считаю, что это извращение.


Роман, кстати хочу отметить особо, что очень здорово , что у тебя сразу возникло такое чувство.
Это значит, у тебя есть правильное реляционное мышление, ну или хотя бы его задатки.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433557
Sgt.Pepper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79Sgt.Pepperпропущено...
И что будет для Рима default value?

Какой язык первичный, такой и писать. Если сайт ориентирован в первую очередь на Запад, то английскийПервичный для города или для коммерческой выгоды?

Как я понял ТС, сайт скорее русско-белорусско-украинский, но не важно.
Если сайт ориентирован прежде всего на Запад, то почему бы не обеспечить в Literal ВСЕГДА наличие написания на английском?
А то вдруг в City будет Roma, а в Literal - 'en, rome'?
Человек, войдя на сайт, выбрал себе итальянский, а ему вместо Ferenze пишут Florence?

Пусть бизнес решил переориентироваться в сторону итальянцев (ну или китайцев) , т.к. они дают весь коммерческий профит - будем менять дефолты? Как?...

Важный вопрос, который со стороны ТС остался без ответа: готов ли он мириться с тем, что набор городов для каждого языка будет разным?..
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433622
Sgt.Pepper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кот Матроскин1. Направление преобразования всегда одно - перевод с родного по отношению к топониму языка на иностранный. Я уже говорил, что считаю задачу автоматического перевода "город Лондон" на английский и на основании перевода идентификации города - неразумной. Другими словами, чтобы письмо дошло до адресата, лучше адрес написать на том языке, который понимает почтовая служба адресата, не очень-то доверяя автопереводу топонимов и самих городов?..
Бинго?..
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433819
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv,

большое спасибо — я уже реализую схему по предложенному варианту. Единственный вопрос, на которые мне пока никто не ответил: как в SQL Server реализовать составной первичный ключ?

Например, вы пишите:

MasterZivЛибо к каждой таблице, где храняться переводимые данные, ты делаешь таблицу с суффиксом (или префиксом) , например, "_INT"
или "_TRANS", где таблица состоит из:

полей PK изначальной таблицы
добавленного в PK идентификатора языка (лучше в виде текстовой константы -- кода языка типа 'RU' 'EN' и т.д.)

Как реализовать фразу «добавленного в PK идентификатора языка» для

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create table dbo.CityTranslation(

    -- Ид. города (ссылается на идентификатор основной таблицы городов).
    id int not null foreign key references dbo.City(id),

    -- Ид. языка перевода (константа).
    langId char(2) not null,

    -- Перевод имени города.
    name nvarchar(64) not null
);

ALTER TABLE dbo.CityTranslation ADD CONSTRAINT PK_IdLangId PRIMARY KEY CLUSTERED (id, langId);



??? — Правильно?
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433822
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> Бинго?

Бинго. Фишка в том, чтобы результат был одинаковым при любом уровне подготовки отправителя и любом используемом им языке. Эта достаточно просто, но решение в этом обсуждении приведено не было.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433836
Sgt.Pepper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenko
Код: sql
1.
ALTER TABLE dbo.CityTranslation ADD CONSTRAINT PK_IdLangId PRIMARY KEY CLUSTERED (id, langId);



??? — Правильно?Да вроде - да... Синтаксис же легко гуглится...
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433844
Sgt.Pepper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
guest_20040621> Бинго?

Бинго. Фишка в том, чтобы результат был одинаковым при любом уровне подготовки отправителя и любом используемом им языке. Эта достаточно просто, но решение в этом обсуждении приведено не было.Давайте для контрастности от английского к суахили?..
Какие там у них топонимы?.. Какие правила у местной почты?..
Может там по индексу все дойдет без единого текстового поля?...

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

Вам не кажется, что это то же самое, что Google Translate?.. - Я не понимаю по испански, мои хозяева - ни по-русски, ни по английски, но мы находим способ как-то понимать друг друга, хотя и не идеально...
Не идеально - это письмо или дойдет или нет, вероятность зависит от качества онлайн-переводчика...
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433906
roman_lenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sgt.PepperДа вроде - да... Синтаксис же легко гуглится...

Ну, на всякий случай нужно переспросить.

Я вот только не понимаю: зачем вы всю эту тему про топонимы завели? — по крайней мере, к моему проекту это отношения уже не имеет — я стараюсь подойти максимально просто — только имена собственные.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433918
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> Давайте для контрастности от английского к суахили?..

Слишком контрастно. Давайте что-нибудь менее экзотическое.

> это когда отправитель не умеет читать и писать на родном языке

Это когда отправитель только и умеет коряво читать и писать на родном языке.

> не кажется, что это то же самое, что Google Translate?

Нет, не кажется. Google предлагает варианты перевода, причём, довольно корявые. Здесь же задача - обеспечить точное соответствие адресов.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38433923
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
> зачем вы всю эту тему про топонимы завели?

Извините, Роман, но тема очень уж интересная. Решение для вашего случая вам подсказали, если будете знать о предметной области чуть больше, чем вам сейчас нужно, - это будет плюсом к вашей квалификации.
...
Рейтинг: 0 / 0
Организация БД мультиязычного сайта
    #38434598
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
roman_lenkoALTER TABLE dbo.CityTranslation ADD CONSTRAINT PK_IdLangId PRIMARY KEY CLUSTERED (id, langId);

??? — Правильно?

Да. Только не обязательно CLUSTERED.
...
Рейтинг: 0 / 0
60 сообщений из 60, показаны все 3 страниц
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Организация БД мультиязычного сайта
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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