Сохранение текстов на разных языках в базе данных
Есть какая то база, в ней ней есть таблицы с полями текста, допустим название города. База отображается через приложение которое имеет выбор языка отображения. Хотя бы нем. и англ.
Выбрал пользователь en показываем Cologne, выбрал de, показываем Köln.
Типа так: https://en.wikipedia.org/wiki/Cologne ,только данные вводит администратор и разных таблиц будет много.
Вариантов имплементации много, что вам больше нравится?
Предложенные варианты:
1. Использовать динамический перевод от гугла.
2. Упаковать в одно поле все языки
3. Использовать паралельные языковые таблицы, где только перевод полей, для каждой таблицы
4. Использовать дополнительное поле для каждого языка в одной таблице CityId, CityNameEn, CityNameRu, CityNameDe, ZIP
5. Глобальное хранилище переводов - "id-язык-перевод" + кэш
Ваш вариант решения.
Так?
Таблица City:
CityID, LangID, Description
Таблицая Language:
LangID, Description
Дальше:
SELECT c.Description FROM City AS c INNER JOIN Language AS l ON c.LangID l.LangID WHERE LangID = .. AND CityID = ...
Например:
Language:
LangID Dscription
1 Русский
2 English
City:
CItyID LangID Description
1 1 Москва
1 2 Moscow
SELECT c.Description FROM City AS c INNER JOIN Language AS l ON c.LangID l.LangID WHERE LangID=1 AND CityID=1
Результат:
Description
Москва
SELECT c.Description FROM City AS c INNER JOIN Language AS l ON c.LangID l.LangID WHERE LangID=2 AND CityID=1
Результат:
Description
Moscow
Сохраняйте название в таблице связей. Отношение * to *.
LangId
LangName
CityId
CityName (например, английское название, или можно вообще выкинуть это поле, т.к. оно будет в таблице связей)
Таблица связей
CityId
LangId
CityName
Что делаем для других языков?
-----
Пишем, укзывая язык.
Еще нужен "язык по умолчанию" - то, что подставится если нет записи на нужном языке.
Подобных таблиц и связей довольно много.
-----
И?
Работы - да, много...
Если хочешь вариант - делаешь ресурсные дллки под языки и работаешь с ними в ручном режиме...
Меньше работы не будет.
Добили Москва и Садовая и сказали что эта улица в Москве для ru.Что делаем для других языков?
Когда я делал портал по недвижимости, то я в каждую таблицу вставлял поле langid. Если у вас не App и не десктопное приложение, а веб приложение, то можно заставить гугл переводить - см. https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/translate. Если поле "улица" не используется для поиска, то ИМХО можно использовать шаблон, использовать разделительные знаки типа |, или сериализовать даже целый объект.
Пример как использовать разделительные знаки типа |:
Садовая|Sadovaya|Sadowaia, а дальше сплитуете см - https://docs.microsoft.com/ru-ru/dotnet/api/system.string.split?view=net-5.0
Пример как сериализовать целый объект:
[Serializable] class Street { public Int32 StreetID { get; set; } public String Description { get; set; } public Street(Int32 StreetID, String Description) { this.StreetID = StreetID; this.Description = Description; } } Street s = new Street(1, "Садовая|Sadovaya|Sadowaia");
Дальше читатет тут https://www.c-sharpcorner.com/UploadFile/a5470d/using-xml-serialization-with-C-Sharp-and-sql-server/
Пример как использовать разделительные знаки типа |:
Садовая|Sadovaya|Sadowaia, а дальше сплитуете
Я про то же спрашивал недавно, когда говорил, как организовать мультилокальность в ресурсных файлах. Сплитить одну строку условными разделителями, писать одну запись несколько раз с разными языками (CityNameEn, CityNameDe, CityNameRu), заводить полноценные отдельные файлы под каждую локаль. Остановился на полноценных отдельных файлах, т.к. оптимальное решение между сильно зажатым вариантом с разделителями (уже не расширишь никак на добавочные требования или поля) и слишком гибким (и сложным) вариантом типа полноценной БД.
У ТС вариантов нет - только БД. На один язык приходится много городов. Один город может быть назван на многих языках. Название конкретного города на конкретном языке - уникальная запись. Вывод - для этого больше подойдёт поле в junction table между таблицами города и языка. И так для каждой связи "сущность - язык": "улица - язык", "город - язык" и т.д.
Ну так это для одной таблицы, а хотя бы для двух и больше? На каждую свою языковую копию делать? И все текстовые поля туда?
Не понял. Приведите пример. Я написал выше такой вариант. Дополню ещё полями и второй таблицей, чтобы было понятнее:
LangId
LangName
CityId
ZIP
Population
CityId
LangId
CityName
AnotherLocalizedCityData
StreetId
FoundationYear
Lang
StreetId
LangId
StreetName
AnotherLocalizedStreetData
Сколько сущностей требуют мультилокальность, столько и таблиц связей. В пределе можно вообще отказаться от отдельной таблицы городов или улиц, если известно, что в них только данные, требующие мультилокальность - т.е. данных типа почтового кода или населения нет. Но обычно это заранее неизвестно или таки такие данные есть, поэтому более гибко будет всё равно завести по отдельной таблице.
то можно заставить гугл переводить
То есть вариант - динамический перевод. Тут тоже проблемы, одно слово правильно перевести часто не получается. И еще непонятно как быть с большим количество запросов? И с задержкой перевода, страницу ведь можно показать только после полного перевода всего что там есть.
Ну так это для одной таблицы, а хотя бы для двух и больше? На каждую свою языковую копию делать? И все текстовые поля туда?
Именно так. Следующий уровень упрощения - вместо таблиц с локализацией делать поля с локализацией
CityId
CityNameEn
CityNameRu
CityNameDe
ZIP
Population
Минус - при добавлении новой локали нужно обновить приложение (обычно требуется обновление ORM). В варианте с отдельными заранее созданными таблицами связей - не нужно.
какую на самом деле задачу решаете.
Есть/проектируется какая то база данных, ну например, поставщики товаров с адресами и товарами.
Таблиц и связей достаточно, уж точно больше десяти.
База заполняется, допустим на немецком. Но есть хотелка, что бы информация записанная в базе была доступна еще и на других языках.
Интересно обсудить варианты решения, найти + и -.
Примерно так. Только связь между городом (улицей) и таблицей связей 1-*.
Или, если я правильно понимаю, если в таблице связей ключ будет составной (из двух айдишников - города и языка, например), то связь между городом и таблицей связей можно сделать 1-1?
Есть/проектируется какая то база данных, ну например, поставщики товаров с адресами и товарами.
Таблиц и связей достаточно, уж точно больше десяти.
База заполняется, допустим на немецком. Но есть хотелка, что бы информация записанная в базе была доступна еще и на других языках.
Интересно обсудить варианты решения, найти + и -.
Т.е. задача идентична городам и улицам. Решение предлагается то же.
По-моему, лучше всё же добавить в таблицу связей отдельный суррогатный ключ, и сделать связи City 1 - * CityLang * - 1 Lang. Но я в базах данных не настолько силён. Как там будет обрабатываться составной ключ, если удалить или обновить, скажем, запись в таблице языков. Одни говорят, что это медленнее, чем когда есть отдельный простой суррогатный ключ для записи, а не составной из айдишников связанных записей. Другие говорят, что дополнительный суррогатный ключ не нужен. Хотя его наличие ничего особо не усложняет и места силно не занимает.
Исключая того, что городов и улиц в базе может не быть вообще.
И не обязательно база реляционная и не обязательно только одна
Я не очень понимаю "нереляционная база данных". Это та, в которой нет связей между таблицами на уровне модели БД - т.е. вы их просто не заводите? Или это та, где сами данные не связаны по сути? Если данные всё же связаны по сути, а вы им связи в БД не делаете, то значит, вы должны их всё равно связать где-то в другом месте.
Как предлагал Мурр, вы можете локализованные данные хранить хоть в ДЛЛках, хоть в ресурсных файлах (как у меня). Но всё равно где-то должны будете прописать, что этот файл относится к такой-то локали и в нём лежит строка, хранящая имя города, например. Т.е. в той же БД создать таблицу, где всё это указать. Т.е. не вижу смысла выходить за рамки относительной БД, если отношения между сущностями в реальном мире так и так есть. Разве что кто-то раньше уже написал всё это именно в нереляционном стиле, а теперь нужно прикрутить локализацию. Ну значит, придётся городить реляционный костыль, покрывая нереляционные данные.
Исключая того, что городов и улиц в базе может не быть вообще.
И не обязательно база реляционная и не обязательно только одна
Крысота. Сначала спросить как решить проблему постройки велосипеда, а потом жаловаться что найденное решение не работает для строительства нефтеналивного причала.
Что надо-то? id-язык-перевод куда-то запихни. Хошь ресурсы, хошь РБД, хошь NoSQL, хошь через REST доступ к данным в CDN делай. Но ни в коем разе не записи для каждого языка "City_EN, City_DE" или лепить несколько переводов в одну запись "Köln|Cologne".
Но ни в коем разе не записи для каждого языка "City_EN, City_DE" или лепить несколько переводов в одну запись "Köln|Cologne".
Почему? Очень быстрое и простое решение. Может, там большего и не требуется.
Если бы кто-то где-то в мире обладал статистикой по принятым архитектурным решениям (пусть даже в разных областях), то уверен, что подобные бы превалировали с большим отрывом.
Почему? Очень быстрое и простое решение. Может, там большего и не требуется.
Такое решение вообще существовать не должно. Только в скриптике, написанном за 15 минут и через 2 дня забытом.
Медленное, хрупкое, плохо скалируется.
то уверен, что подобные бы превалировали с большим отрывом.
Не сомневаюсь. "95% людей - идиоты"
И с задержкой перевода, страницу ведь можно показать только после полного перевода всего что там есть.
Вообще база данных нужна в основном для поиска. Я бы перевод хранил бы в XML или в JSON формате. Когда буду делать один проект, всё будет храниться в формате HTML или в формате JSON.
Если не писать дурацких запросов с условиями, где вытаскиваются длинные строковые поля, что-то там сравнивается, сплитится, мерджится, а тупо по айдишникам и связям, то всё будет работать быстро и чётко. А всякие интероперабилити с подгрузом ДЛЛек, открытием файлов, чтением их и прочая муть сожрёт всю производительность. Толкай всё в БД и не думай, если объёмы не сверхбольшие.
Я так понимаю некий глобальный ресурс? А как потом редактировать запись в таблице, через посредника?
Да кто ж тебя знает. Куда надо. Что ты делаешь-то? Может тебе надо десктопное приложение, способное работать в оффлайне. Тогда отдельная ДБ и доступ к онлайн ресурсам слегка затруднён. А может клиент-сервер? Тогда ДБ хорошее решение. А может веб-приложение доступное по всему миру? CDN в руки. Редактировать часто будем? Да - скорее БД. Нет - скорее CDN/ресурсы. Объём данных? Большой - БД/CDN. Маленький - ресурсы. Крохотный - да хоть в код влепи.
И как он интересно тута попадёт?
Так-же как и в БД. Только XML это устаревший вариант, сейчас модно JSON. Пример:
index.html:
<!DOCTYPE html> <head> <title>Test</title> <script> var lang = 'ru'; window.onload = () => { fetch('demo.json').then(response => response.json()).then(data => { let json_items = JSON.parse(JSON.stringify(data)); let el = document.getElementById('city'); for(let index=0; index<json_items.cities.length; index++) { let new_el = document.createElement('option'); new_el.setAttribute('value', json_items.cities[index].id); new_el.innerHTML = json_items.cities[index][lang]; el.appendChild(new_el); } }); } </script> </head> <body> <select id="city"> </select> </body>
demo.json:
{"cities": [ {"id":1, "ru":"Moskva", "de":"Moskau", "en": "Moscow"}, {"id":2, "ru":"Keln", "de":"Köln", "en":"Cologn"} ] }
Результат см. https://i.ibb.co/LQkd6QJ/json-demos-result-min.jpg
Вообще если использовать NOSQL то проблема решается в два счёта. См.:
https://i.ibb.co/Kyz0zG5/mongo0-min.jpg
А как записывать то?
Пример (Backend):
using System; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { File.AppendAllText("testappend.html", "Предпоследняя строчка \n"); File.AppendAllText("testappend.html", "Последняя строчка \n"); } } }
немного странновато, клиент читает локальный файл.
Обращается http:///.../testappend.html и видит в браузере:
Предпоследняя строчка Последняя строчка
Вариантов имплементации много, что вам больше нравится?
извините, не читал всю ветку, но этого маловато. вопрос не в том, что мне нравится, а чего ожидает заказчик. или он хочет переводы гуголя, или он хочет лично присылать вам переводы, и вы их будете вносить в базу, или ...
А где же XML или Json? И что делать если два человека что то редактируют? И как изменить москва в какой-то неизвестной строке? А если весь файл в память не помещается?
Я безпонятия о чём речь честно говоря. В своём будущем проекте immobilien portal я буду использовать статические JSON и HTML.
Так бы примерно бы делал бы:
using System; using System.IO; using System.Collections.Generic; using System.Text; namespace Backend { class Program { private static String Replace(String strTemplate, Dictionary<String, String> dicData) { StringBuilder stbData = new StringBuilder(strTemplate); foreach (KeyValuePair<String, String> item in dicData) stbData.Replace(item.Key, item.Value); return stbData.ToString(); } private static void Generate(String strTemplateFile, String strTemplateExpose, Dictionary<String, String> dicExposeItems, Dictionary<String, String> dicTemplateItems, String strOutput) { String strPath_expose = Directory.GetCurrentDirectory() + strTemplateExpose; String strPath_template = Directory.GetCurrentDirectory() + strTemplateFile; String strPath_output_html = Directory.GetCurrentDirectory() + strOutput; String strBuffer = File.ReadAllText(strPath_expose, Encoding.UTF8); String strBuffer2 = File.ReadAllText(strPath_template, Encoding.UTF8); dicTemplateItems.Remove("{content}"); dicTemplateItems.Add("{content}", Replace(strBuffer, dicExposeItems)); File.WriteAllText(strPath_output_html, Replace(strBuffer2, dicTemplateItems), Encoding.UTF8); } static void Main(string[] args) { String strLang = "en-us"; String strNow = DateTime.Now.ToString(); Dictionary<String, String> dicExposeItems = new Dictionary<string, string>(); dicExposeItems.Add("{InseratID}", "1"); dicExposeItems.Add("{CreateDate}", strNow); dicExposeItems.Add("{Title}", "House, 3 rooms"); dicExposeItems.Add("{CntRooms}", "3"); dicExposeItems.Add("{Description}", "House, 3 rooms"); dicExposeItems.Add("{Square}", "70"); Dictionary<String, String> dicTemplateItems = new Dictionary<string, string>(); dicTemplateItems.Add("{lang}", "en"); dicTemplateItems.Add("{title}", "House, 3 rooms"); Generate(String.Format(@"\template.{0}.xml", strLang), String.Format(@"\expose.{0}.xml", strLang), dicExposeItems, dicTemplateItems, String.Format(@"\demo.{0}.html", strLang)); strLang = "ru-ru"; dicTemplateItems.Remove("{lang}"); dicTemplateItems.Add("{lang}", strLang.Substring(0, 2)); Generate(String.Format(@"\template.{0}.xml", strLang), String.Format(@"\expose.{0}.xml", strLang), dicExposeItems, dicTemplateItems, String.Format(@"\demo.{0}.html", strLang)); strLang = "de-de"; dicTemplateItems.Remove("{lang}"); dicTemplateItems.Add("{lang}", strLang.Substring(0, 2)); Generate(String.Format(@"\template.{0}.xml", strLang), String.Format(@"\expose.{0}.xml", strLang), dicExposeItems, dicTemplateItems, String.Format(@"\demo.{0}.html", strLang)); } } }
Результат см.:https://i.ibb.co/Z1stvX4/r-min.jpg
Я так понимаю некий глобальный ресурс?
-----
Да нет - чисто твой выбор способа хранения.
А как потом редактировать запись в таблице
------
А это тебя сейчас не должно волновать...
Ввел на одном - получил перевод на каждый из заданых языков - пихнул в хранилище...
И это... в базах таблицы бывают и без первичных ключей, и со множествеными полями в качестве уникального ключа...
Извините за вопрос не по теме. Вы обычно сами систему авторизации пользователей (хранение и смена паролей, длину сессий и прочее) разрабатываете, или какие-то готовые модули используете? Деплоите сами, с настройкой сертификатов шифрования и вообще веб-сервера, или тоже что-то готовое используете?
https://medium.com/walkin/database-internationalization-i1...
например. текст - это ещё небольшая проблема
Загнать все тексты и переводы в уникодный txt, сделать zip/7z и в программе просто считывать из архивного файла нужный текст по связке id-страна & id-(текстовое поле).
Доп. плюс - всегда легко и быстро можно отредактировать базу или дополнить ее новыми языками.
Можно даже маленькую программку для управления такой базой "на коленке" написать.
https://medium.com/walkin/database-internationalization-i1...
например. текст - это ещё небольшая проблема
Вот я и предлагал последний вариант изначально. И да - не составной ключ из айдишников языка и переводимой сущности, а простой отдельный суррогатный.
А даты и прочее обычно форматируются из коробки (в правильном фреймворке) по выбранной культуре.
а что мы вообще разрабатываем? с этого бы начать. не определившись с задачей, попытки поскорей начать "имплеменментировать" - суета-сует.
если же исходить из того, что задача полностью определена в заглавии (Сохранение текстов на разных языках в базе данных), то три таблицы напрашиваются:
create table language (id int(11) not null, language varchar(20) not null, symbol varchar(10));
create table text (id int(11) not null, text text not null);
create table translation (id int(11) not null, text_id int(11), lang_id int(11), translation text)
и еще. в промежности между "приложением" и базой нужен какой-то "локализатор", который будет иметь удобный интерфейс и будет знать, как из запрошенного приложением получить от базы нужный текст. потому что простого "сохнанения текстов на разных языках" обычно оказывается недостаточно.
По предлагаемой схеме тебе надо будет писать два разных метода получения текста - один для оригинального, другой для перевода.
При этом язык оригинального текста - неопределен.
Ворос тут скорее в том, где хранить информацию об языке - вместе с текстом или делать отдельный маппер...
Текущая культура в Дотнете хранится в CultureInfo. Дефолтная - под которой запущено приложение. Если это сайт на сервере - культура на сервере. Надо клиентскую - спрашиваешь в браузере у клиента какая или берёшь из настроек текущей сессии клиента. Кодировки культур имеют известный формат. Из приложения получаешь кодировку и сущность, которую нужно перевести. Далее что там у нас, EntityFramework? Тогда что-то типа
Lang.LangCityTranslations.Where(t => t.LangId == ... && t.CityId == ...).FirstOrDefault()
и далее вытаскиваешь нужное для перевода свойство.
По предлагаемой схеме тебе надо будет писать два разных метода получения текста - один для оригинального, другой для перевода.
нет никакого "оригинального", если вы его искусственно не создали. просто текст-ключ. например, "жопа". выдаем запрос таблице text получить id слова жопа, таблице language - запрос на id языка XY, и уже с этими двумя идями обращаемся в таблицу translate за текстом "жопа" на нужном языке.
При этом язык оригинального текста - неопределен.
что такое "оригинальный текст"?
Ворос тут скорее в том, где хранить информацию об языке - вместе с текстом или делать отдельный маппер...
ну да, это - самый главный вопрос... подумайте, как решить, может, что придумаете ...
Текущая культура в Дотнете хранится в CultureInfo.
откуда появился дотнет и прочее? кто сказал, что здесь вообще присутствует дотнет или иное? вопрос: как сохранить тексты на разных языках в базе данных. "остальное - от лукавого" (с)
просто текст-ключ.
-----
Заметь - это не Я написал.
При этом Я как-то не увидел на каком языке текст...
обращаемся в таблицу translate
-----
Что именно требует обращаться в эту таблицу?
Каков будет результат для заданого исходного с языком "русский"?
что такое "оригинальный текст"?
-----
Нннннну скажем что это текст для которого нет информации об языке.
подумайте, как решить
-----
Пару варианнннтов Я когда-то делал...
Тексты сохранить в отношении много ко многим в таблице связей. А дотнет - просто как пример, откуда возьмётся дефолтная культура. Неважно, дотнет или нет - всё равно выбор текущего языка неплохо бы поместить в настройки аккаунта.
Не понятно, что вам непонятно. Весь текст, включая интерфейс, или лишь его куски, требующие перевода, подставляются в виде переменных, в которых оказывается перевод согласно выбранной локали.
Я последние свои проекты - пару сайтов и WPF-приложение - сделал все с поддержкой локализации. И сейчас игру на Юнити делаю по тому же шаблону. Только я не в БД всё запихал, а в словари ресурсов, но суть от этого не меняется.
Всплыл недостаток сохранения локализованных данных в файлах resx. resx генерит в выходную директорию папки с названиями локалей и в каждой DLL с одним и тем же именем. Если я хочу импортировать эти DLL в, скажем, Юнити, то возникает ошибка - туда можно импортировать только одну DLL с тем же именем, при этом неважно, что они в разных директориях находятся. Придётся либо отказаться от хранения локалей, как это требуется для resx, либо придумать своё хранилище.
Самый простой вариант обойти это - отказаться от схемы "отдельный файл на локаль" и встроить обозначение локали в имя ресурса - типа "PersonName_en_US". А вытаскиваться ресурс через символы подстановки - типа
resourceManager.GetString($"PersonName_{locale}");
Но если ресурсы уже сохранены с прежней схемой, то куча работы по переписыванию - ручному или программному. Ну и теперь ломается схема работы с локалями самого класса ResourceManager.
Ещё как вариант - создать по сборке на каждую локаль и передавать в конструктор ResourceManager сборку текущей выбранной локали. Проблема только в том, что придётся отдельный проект для каждой такой локали делать, чтобы каждый проект свою DLL выпускал.
В МСДНе везде про resx файлы говорится и класс ResourceManager
Globalize and localize .NET applications | Microsoft Docs
Если есть способ заставить это всё дело сохранять локализованные ресурсы в DLL с разными названиями или в одну DLL, то для Юнити пойдёт. Нет - нужно искать другой подход. В Дотнете локализованные ресурсы сохраняются в либы с одним и тем же названием, но в разных папках.
С одной стороны вы говорите, что нужно быстро решать задачи. С другой - на каждый вопрос предлагаете максимально глубокое и долгое изучение, вместо ответа на конкретный вопрос. Если, конечно, вы знаете ответ.
Я импортирую в Юнити ДЛЛки. Юнити пишет, что не должно быть ДЛЛек с одним именем, неважно, как они раскиданы по директориям - Юнити нашёл в разных директориях одинаковые по имени ДЛЛки и не даёт их импортировать. Всё. Диапазон решений - либо одна ДЛЛ, либо много с разными именами, либо вообще другой подход, типа текстовых файлов (txt, xml, json, etc.).
...изучение...
-----
Для твоей же пользы - у тебя один из пробелов в навыках - работа с документацией. Просто не умеешь быстро находить нужное.
Вот Я тебя и отсылаю к документации - читать, разбираться и получать навык эффективной работы с доками.
Ты либо научишься учится, либо будет как сейчас.
А задачи - задачи надо решать быстро.
А для возможности решать быстро - надо дохрена и больше знать.
Ну а чтобы знать - надо ... учится. Много и постоянно.
Тут - без вариантов.
Не дает их импортировать
-----
А должен?
Читай доку на предмет типов ресурсов.
Потом будешь изучать как управлять (если стандарта не хватит) загрузкой и что надо для связывания ресов.
ответ дайте.
-----
А если не дадут то и решения не будет?
А всего-то - надо изучить организацию и использование ресурсов.
И, кстати, ресурс - американский... в основном... а для американцев не существует проблемы локализации в виду отсутствия не-американского языка...
А если не дадут то и решения не будет?
А всего-то - надо изучить организацию и использование ресурсов.
И, кстати, ресурс - американский... в основном... а для американцев не существует проблемы локализации в виду отсутствия не-американского языка...
Если ответа не будет, то придётся самому изучать или что-то своё лепить. Но ответ всё это дело ускорит.
Всё они локализуют. Локализации нет в игрушках в Стиме, в магазинах приложений, или в нормальных программах, типа того же Фотошопа?
Не вопрос - не будет задачи, не буду локализовать. У меня на прежних работах никто не требовал локализации - достаточно было русского. Я сам на сайте и потом в WPF себе прикрутил. А с Юнити старый простой подход по МСДНовскому букварю не сработал - нужны танцы с бубном и копошения в кишках, как там эти ресурсы хранятся-деплоятся-обрабатываются.
достаточно было русского.
-----
А америкосам - достаточно американской версии английского.
И то, что в мире есть другие языки для многих мамерикосов - тайна за семью печатями.
Вот простой пример.
Винда 7. Обычные региональные настройки.
Мне нужны одновременно - американская клава, русская клава и... формат даты dd/mm/yyyy.
или что-то свое лепить.
-----
Флаг тебе в руки, барабан на шею и вперед, возглавлять колонну уволенных изобретателей лисапедов...
Прочитал тут всё
Create satellite assemblies for .NET apps | Microsoft Docs
Package and deploy resources in .NET Apps | Microsoft Docs
Resources in .NET apps | Microsoft Docs
Херня и вода - для моего вопроса ответа не дают. Единственный намёк - затолкать эти сборки-сателлиты (как раз те, что содержат сокмиленные ресурсы для локали) в глобальный кеш сборок, но там могут быть проблемы с доступом из Юнити. Да и на разных системах это в разных местах находится - Винда, Андроид и прочее. В моём случае лучше, когда всё в папке приложения лежит.
Сейчас видится такое решение - создать по проекту для каждой локали, дать сборкам разные имена (например, поместить в название имя локали), чтобы Юнити не ругался при импорте, загружать при старте приложения ту сборку, чья локаль выбрана.
Эй, кто мне минусы лепит? Лучше ответ дайте. ))
А там ведь платно вроде бы, не? Если платно, то сомневаюсь что кто-то зареган из этого форума там. Ну это всегда так, сплошные хейтеры и тролли. Влепил кто-то дизлайк, и спрятался.
Короче, в Юнити сделано всё так, чтобы максимально усложнить тебе жизнь при использовании чего-то не из Юнити. Поэтому ставишь тамошний плагин по локализации или покупаешь чего-то в ихнем магазине плагинов и не выё... Юнити, похоже, больше зарабатывает на продаже всяких штук в своём магазине для разработчиков, чем на просто лицензиях своего движка, поэтому всё, что стороннее и не из стора - максимально затруднено для интеграции.
В самом универсальном решении всего одна таблица связей добавляется, и лишь для информации, которая требует локализации. По наблюдениям за другими сайтами, в том числе крупных компаний, некоторые предпочитают вообще разные версии сайтов для каждой локали держать. Лишь похожие элементы оформления и стилей используют. Ну это у кого денег и времени много.
Неа. Предложенное решение - лучшее с точки зрения организации и дальнейшей поддержки. Для скорости лучше, наверное, завести в таблице столько вариантов одного поля, требующего локализации, сколько самих локалей предусмотрено. Тогда будет так же быстро, как и обычное обращение к таблице БД без локализации.
Конечно есть! Причем - больше одного варианта.
Но чтобы понимать что надо делать - надо изучать базы чутка глубже, чем написание селектов...
И, можешь смеятся, надо будет освоить работу с файлами... в том числе - с большими (больше размера памяти) файлами... об чем тебе давалась элементарная задачка.
Тут что-то написали https://stackoverflow.com/questions/537204/localisation-i18n-of-database-data-in-linq-to-sql
Конечно есть! Причем - больше одного варианта.
Но чтобы понимать что надо делать - надо изучать базы чутка глубже, чем написание селектов...
И, можешь смеятся, надо будет освоить работу с файлами... в том числе - с большими (больше размера памяти) файлами... об чем тебе давалась элементарная задачка.
Размера какой памяти? БД и не держит все таблицы в оперативке. Или вам нужна локализация многих текстов размерами в гигабайты каждый?
А если задача не стоит делать всегда и обязательно рекордные БД (ну не все тут Гуглы или обрабатывают миллиарды записей), то таблицы связей и локализованные поля начинают работать? Ведь конкретное решение зависит от задачи:
1) вас устраивает тупой говнокод - даже с ним ничего не тормозит;
2) вас устраивает простое следование простым примерам из букварей;
3) вас устраивает просто хорошо написанная БД в стандартной СУБД;
4) вы делаете какие-то хаки-доработки для стандартной СУБД и экспериментируете со схемами БД;
5) вас уже не устраивает стандартная БД и хаки-доработки не помогают, вы делаете свою БД, заточенную под ваши задачи.
Ваши советы почти всегда из разряда не ниже 4. Тогда как подавляющее число задач решается способами 1-3.
И вы не могли бы почаще давать конкретные советы, как и что именно тут и здесь можно сделать, а не общие, типа почитай этот толмуд, пройди этот курс?
Есть вариант сделать мультиязычность быстрее, чем во второй таблице?
А зачем тут 2 таблицы :)
Я бы сделал так:
T_En
id
text
T_Ru
id
textT_De
id
textСобственно говоря, лет 15 тому назад мы так и сделали.
Логика менеджера была простая как мычание :
1) Взять строку из T_xx
2) Если строки нет, то взять строку из T_En
3) Если строки нет, то вернуть id
А для того, чтобы сразу было видно, прошла ли эта строка через менеджер, в дебаг моде к каждой строке добавлялся префикс '###'.
Все просто и понятно. При этом сразу видно какие строки берутся из БД, а какие хардкодед. И всегда можно легко найти строки без перевода.
А зачем тут 2 таблицы :)
Я привел пример двух таблиц - без локализации и с. И в какой будет производительность больше и насколько? В смысле, что так ли уж критично использовать какой-то особенный подход с изъё...вом в архитектуре или подключением обычных файлов с диска?
Я бы сделал так:
Имеет право на существование. Но. Добавлять новый язык будет не так просто. И если уж мы заботимся о скорости... Такое решение будет медленнее джойна с таблицей с локализованными текстами.
Потому что менеджер явно на стороне приложения. А значит на поиск перевода тратит новый запрос. А раундтрип у запроса раз в ... 10? больше стоимости джойна вроде
SELECT а.*, c.text as CITY_LOC FROM ADDRESS a JOIN I18_TEXT c ON a.CITY_NAME_ID = c.ID AND c.LANG = "en" WHERE ....
Я бы сделал так:
Вы просто храните все локализованные тексты в таблицах по одной на язык. А подключаете их как? Типа такого?
T_Item
id description - id from T_En
Как выбор таблицы с нужной локалью происходит?
НП.
Наверное нужно применять LINQ, там можно разную магию делать, насчёт СУБД в память, есть In Memory DB - https://docs.microsoft.com/ru-ru/sql/relational-databases/in-memory-database?view=sql-server-ver15
И вы не могли бы почаще давать конкретные советы
-----
Тебе снова сказать про фрагментированность твоих знаний?
Ни один, ни сотня конкретных ответов в этом плане ничего не поменяют, а только усугубят ситуацию.
почитай этот толмуд, пройди этот курс?
-----
А что делать, если ты сам не учишься? Учить-то за тебя никто не будет...
Похоже, что и тебя учить тоже никто не будет.
из разряда не ниже 4.
-----
Вообще-то - чистая 3.
Только чтобы это понять надо знать чутка больше чем написание селекта. Не на много, но все же больше.
лет 15 тому назад мы так и сделали
-----
Угу... А во что выльется добавление еще одного языка?
Я бы сделал так
-----
Ну а Я бы почитал про партиционирование...
По задаче - не вижу никаких преимуществ в куче дублирующих таблиц, тем более что базы, в большинстве своем, имеют встроенный механизм для разнесения данных аналогично предложенному.
Добавлять новый язык будет не так просто.
Зависит от реализации. Установив правила имен таблиц, новый язык можно добавлять путем добавления соответствующей таблицы в БД :)
Потому что менеджер явно на стороне приложения.
Менеджер просто генерит запрос: $"SELECT * FROM Translation_{cultureInfo.TwoLetterISOLanguageName} WHERE Id = {id}"
Если хочется, то можно сразу джойнить английскую (дефолтную) строку.
Угу... А во что выльется добавление еще одного языка?
В добавление еще одной таблицы. Даже код менеджера не надо править :)
По задаче - не вижу никаких преимуществ в куче дублирующих таблиц, тем более что базы, в большинстве своем, имеют встроенный механизм для разнесения данных аналогично предложенному.
Мы это все делали на SQLite.