powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Локализация веб-проекта (БД, взаимодействие)
10 сообщений из 10, страница 1 из 1
Локализация веб-проекта (БД, взаимодействие)
    #38081071
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
После 25-ой переделки, оптимизации базы и механизма работы пришел к выводу, что это все равно не то ...

Проект: Spring MVC, Spring Security, Hibernate, JSP+JSTL+Spring tags, клиент с jQuery+зависимые библиотеки.
Проект мультиязычный, причем количество языков динамическое и должно определяться админкой, то есть структура таблиц типа "ID, TITLE_RUS, TITLE_ENG, TITLE_FRA" не проходит, так как а) плохо изменяема; б) вне зависимости от используемого языка выборка будет тянуть за собой варианты написания на всех языках. Тем более, сущностей уже много на начальном этапе (проект только на начальной стадии, а уже содержит пару десятков таблиц с мультиязычными текстовыми метками). Любое последующее внесение изменений в БД превратится в кошмар. Интересны были бы решения, которые используются в крупных веб-проектах, типа социальных сетей - там подобного должно быть очень много.

1 вариантом было использование Spring'овского Resource Bundle Message Source в комплексе с БД: таблицы не содержат языковых значений, а только идентефикатор, типа такого
id country1 usa2 canada а локализованные текстовые файлы (bundles - "messages_XX.properties") содержат все "включения" языковых меток в проекте, в том числе отображение значений БД. Применительно к примеру это может быть:
messages_ru.properties:
Код: plaintext
1.
    countries.usa=США
    countries.canada=Канада
и т.д.
Однако это тупиковое направление, причем, "тупиковость" наблюдается сразу по нескольким аспектам:
- объем памяти, которое занимают константы, растет с поразительной скоростью - для 2 десятков таблиц БД размер с метками уже мегабайты (х на количество языков), а стек не безразмерен и уже имеет место периодический PermGen;
- удобство редактирования крайне сомнительно, даже если заводить много разных properties под разные структуры: работать с текстовым файлом при потенциально возможным конкурентным доступом не очень удобно;
- обновление языковых меток в проекте крайне неудобно: пока не задавался вопросом, как при изменении файла properties заставить Spring автоматически обновить значения внутри - не думаю, что это сложно, однако при большом количестве запросов вижу потенциальную опасность такого динамического изменения (как минимум - задержка).

2 вариант, который используется в настоящее время, и который (как оказалось) наиболее освещен в публикациях на тему "оптимальные решения для мультилокальных веб-проектов" - это отделение таблиц данных от таблиц с языковыми константами. Приведу пример на основе той же таблицы стран:
Country
id defaultValue nativeValue1 USA USA2 Canada Canada3 Ukraine Україна
(можно и без поля по умолчанию)
Language
id defaultValue nativeValueen english englishua ukrainian українськаru russian русский
CountryTitle
id language country_id value1 en 1 USA2 en 2 Canada3 en 3 Ukraine4 ua 1 США5 ua 2 Канада6 ua 3 Україна7 ru 1 США8 ru 2 Канада9 ru 3 Украина
Если четко следовать законам релятивистских БД, то такая структура последней таблицы немного избыточна, но зато она компенсируется скоростью выборки, так как добавление еще одной таблицы заметно усложнит запрос (из-за двух "лишних" JOIN'ов).

В принципе, если бы данные выбирались только для создания локализованных списков, то пользоваться весьма удобно. Например, выборка всех стран на нужном языке выглядела бы примерно так (на HQL):
Код: plsql
1.
SELECT title.country.id, title.country.nativeValue, title.value FROM CountryTitle title WHERE title.language.id = :language ORDER BY title.value


Причем, для повышения юзабилити, можно ввести "приоритетность" языков - когда нет значения для выбранного языка, производить выборку значения для приоритетного языка. Запрос значительно усложняется, но он создается разово в ДАО и работать будет одинаково при редактировании таблицы языков и изменении приоритетности языков.

Я бы остановился на этом методе, однако все больше и больше сталкиваюсь с неудобствами, которые заключены в таком соединении таблиц. Главным недостатком, являющимся ключевым для последующих, - это работа не с выбранной из базы сущностью, а с архивом объектов, который получается в результате вышепреведенного запроса. Допустим, если полей несколько, то запутаться в countries[0], countries[1], countries[2] сложно, а если их десятки, то могут быть проблемы. Не буду приводить другие причины - они достаточно субъективны, все они заставляют слишком скурпулезно подходить к обработке данных в контроллере и представлении, которые получены в ДАО. Боюсь, что когда в последующем понадобится возвращаться и менять что-либо, добавлять или исправлять, то это будет весьма затруднительно.

Появились идеи. Их две.
1. В POJO сущности добавить поле с @Transient, которое должно при выборке заполняться локализованным значением. В этом случае работа в представлении будет удобно вестись с сущностью, а не набором значений.
Практически данный способ почти решает все вопросы. Вот только не знаю, как можно получить сразу выборку уже готовых объектов с локализованными значениями, минуя лишний слой, где будет осуществляться обновление сущностей строковыми локализованными значениями. В идеале было бы здорово что-то типа такого (на основе сущности Country с полем value, обозначенным как @Transient):
Код: plsql
1.
SELECT NEW Country(title.country, title.value) FROM CountryTitle title WHERE title.language.id = :language ORDER BY title.value


Как сделать?

2. Совместить приведенные вначале способы, но Resource Bundle привязать не к properties-файлам, а к БД, причем, к NoSQL-базе, скажем, MongoDB. Из того, что я посмотрел и почитал (опыта практической работы с NoSQL и непосредственно MongoDB нет), получение, да и вся работа с базой, базируется на JSON-представлении как запросов, так и данных, что уже само по себе достаточно близко по духу к веб-проекту.
Идея совершенно гипотетическая, исследования в эту сторону не проводились, а курочить текущий проект для "попробовать" не очень хочется, поэтому общараюсь тут с вопросами: есть ли подобный опыт? нормально ли будут "вести себя" SQL-база и NoSQL-база в одном проекте, не сопряжено ли это с трудностями и проблемами? есть ли опыт настройки Spring'овского Resource Bundle на БД (и, в частности, на NoSQL БД)? - кстати, не нашел в пакетах Spring похожих по смыслу классов, как с этим обстоят дела?

Буду признателен за ответы и советы.
...
Рейтинг: 0 / 0
Локализация веб-проекта (БД, взаимодействие)
    #38081232
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не вникая в тонкости..
хранить в таблице в виде дерева
язык - термины на языке - место термина
вводишь новое место -во всех языках появляется пустое место - его и заполняешь.
одна таблица, число языков и терминов не ограничено
легко формализуется для добавления и извлечения
...
Рейтинг: 0 / 0
Локализация веб-проекта (БД, взаимодействие)
    #38082848
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1 вариант реализовал. Правильным было направление, ошибочна реализация, поэтому сразу не получилось. Очень удобно и можно убрать из ДАО методы работы непосредственно с локализованными значениями - они теперь будут вставляться при выборке сущностей.

Но столкнулся с такой проблемкой ... Применительно к рассматриваемому примеру со страной: допустим, есть сущность Address, у которой есть поле Country country (ManyToOne). Выбираем определенный address. Естественно, у объекта address.getCountry() Transient-поле localizedTitle (которое я использую для временного хранения локализованного значения из зависимой таблицы CountryTitle) равно null, так как оно не персистентное и автоматом не заполняется.

Так вот, вопрос заключается в том, как наиболее правильно и оптимально сделать автоматическую выборку при подобных запросах, когда надо зависимый объект переназначить, заполнив нужное поле значением? - Можно, конечно, для каждого метода прописывать по нисходящей заполнение всех объектов, но уж больно огромными станут запросы, а их много - дурной труд. А если надо вставить метку в 5 зависимых объектов? - тысячи символов в запросе ... Можно использовать @Formula, но если выборка приличная по размерам, то делать подстановку каждому объекту RequestContextUtils.getLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()).toString() - это как-то неправильно: POJO - модель, а это выражение - часть контроллера, засорять структуру не хочется, да и лишних вычислений навалом. Есть ли грамотный выход?
...
Рейтинг: 0 / 0
Локализация веб-проекта (БД, взаимодействие)
    #38085589
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Провел анализ наиболее часто используемых решений (не путать с оптимальными!, так как понятия не взаимоисключающие) и пришел к выводу, что акцент ставится на нескольких аспектах, применительных к массовому веб-проекту:
- любая база фактически должна стать хранилищем изолированных хранилищ "ключ-значение";
- исключить внешние ключи и JOIN в запросах;
- для ориентированного под веб и тем более социального приложения максимально переходить на NoSQL-базы, у которых несоизмеримо упрощается горизонтальное масштабирование, а также значительно быстрее работает запись;
- подключать системы кеширования (судя по использованию, лидируют memcashed и Redis);
- не придумывать велосипеды с полнотекстовыми поисками в базе и тем более не использовать встроенные - специализированные проекты типа Sphinx, Solr и прочие справляются с этим несоизмеримо лучше лучше (включая лексемные нюансы).

Проделанный анализ, к сожалению, подталкивает к неутешительным выводам:
- резко уменьшается роль RDBMS (если и вовсе не уходит) - вижу разве что для реализации дерева зависимостей, хотя и это расплывчато;
- сходит на нет удобство ORM, точнее, уход от универсального и удобного Hibernate к специализированным проектам;
- красивое и удобное программирование жертвуется в угоду производительности и скорости, превращая изящную структуру в банальное прокидывание данных из базы клиенту и наоборот.

Такие вот неутешительные выводы ((((. От небольшого специализированного вопроса перешел к переосмыслению всего проекта в целом, так как при росте аудитории все равно прийдется менять рельсы ...
...
Рейтинг: 0 / 0
Локализация веб-проекта (БД, взаимодействие)
    #38091137
Йуный джавистЪ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
исключить внешние ключи и JOIN в запросах;

Неоднократно встречал этот (ошибочный) совет. Посмотрите http://docs.oracle.com/cd/E11882_01/server.112/e16638/data_acc.htm#i12132 если вам интересен этот вопрос.
...
Рейтинг: 0 / 0
Локализация веб-проекта (БД, взаимодействие)
    #38091314
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, интересен. Все на эту тематику интересно.
Что до ошибочности - согласен, с идеологической стороны - полный бред. Но есть практика ... Перечитал построение баз и работы полтора десятка крупнейших соцсетей - ВЕЗДЕ придерживаются такого правила, вне зависимости от ЯП, платформы и БД. Кстати, перестроил работу БД - улучшения явные, не так удобно пользоваться всем и сразу, но универсализация общей работы и интернационализации налицо. Позже добавлю еще NoSQL-БД. И явно начинаю понимать почему они идут по такому пути - глупый подход, но зато он решает массу проблем, в основном архитектурных, и, как следствие, - материальных. Мне, конечно, рановато об этом думать, но "плох тот солдат ..."
...
Рейтинг: 0 / 0
Локализация веб-проекта (БД, взаимодействие)
    #38091362
Йуный джавистЪ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторЧто до ошибочности - согласен, с идеологической стороны - полный бред. Но есть практика

Оракл можно попросить, чтобы он связанные записи в master и details таблицах хранил в одном блоке жесткого диска. Таким образом, никакой нужды в самодельной денормализации нет. При этом, перейти к какому-то другому способу хранения данных на диске (оптимизированному под другие запросы) можно одной командой alter table.
...
Рейтинг: 0 / 0
Локализация веб-проекта (БД, взаимодействие)
    #38091363
Йуный джавистЪ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПеречитал построение баз и работы полтора десятка крупнейших соцсетей - ВЕЗДЕ придерживаются такого правила, вне зависимости от ЯП, платформы и БД.

В соцсетях, по-моему, выгоднее все партиционировать по дате создания. В противном случае, чтобы показать профайл пользователя, придется читать с диска его посты и коменты трехлетней давности, которые никому уже неинтересны.
...
Рейтинг: 0 / 0
Локализация веб-проекта (БД, взаимодействие)
    #38091484
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Йуный джавистЪВ соцсетях, по-моему, выгоднее все
+1
соцСети и Учётка - совершенно разная архитектура хранилища.
IDVsbruckакцент ставится на нескольких аспектах, применительных к массовому веб-проекту:
сабж вроде про локализацию _сайта_, а не массовый веб проект.
Если убрать локализацию - то нет проблем?
Так что сравнивать РДБМС и ООБД ещё рано.
...
Рейтинг: 0 / 0
Локализация веб-проекта (БД, взаимодействие)
    #38092477
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, ты прав ... вопрос как бы перетек с одного в другое. Хотя на самом деле это я его сначала так сформулировал, так как видел проблему реализации только в той части, которая касалась локализации - структура всего остального вроде не представляла проблемы. Однако в процессе "раскрутки" вопроса все свелось немного к другому. А так как при решении задачи пришлось начитаться всякого, то решение я нашел именно в таком подходе. Заканчиваю переносить сделанное на новые рельсы и пока не жалею.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Локализация веб-проекта (БД, взаимодействие)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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