|
|
|
Локализация веб-проекта (БД, взаимодействие)
|
|||
|---|---|---|---|
|
#18+
После 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. Однако это тупиковое направление, причем, "тупиковость" наблюдается сразу по нескольким аспектам: - объем памяти, которое занимают константы, растет с поразительной скоростью - для 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. Причем, для повышения юзабилити, можно ввести "приоритетность" языков - когда нет значения для выбранного языка, производить выборку значения для приоритетного языка. Запрос значительно усложняется, но он создается разово в ДАО и работать будет одинаково при редактировании таблицы языков и изменении приоритетности языков. Я бы остановился на этом методе, однако все больше и больше сталкиваюсь с неудобствами, которые заключены в таком соединении таблиц. Главным недостатком, являющимся ключевым для последующих, - это работа не с выбранной из базы сущностью, а с архивом объектов, который получается в результате вышепреведенного запроса. Допустим, если полей несколько, то запутаться в countries[0], countries[1], countries[2] сложно, а если их десятки, то могут быть проблемы. Не буду приводить другие причины - они достаточно субъективны, все они заставляют слишком скурпулезно подходить к обработке данных в контроллере и представлении, которые получены в ДАО. Боюсь, что когда в последующем понадобится возвращаться и менять что-либо, добавлять или исправлять, то это будет весьма затруднительно. Появились идеи. Их две. 1. В POJO сущности добавить поле с @Transient, которое должно при выборке заполняться локализованным значением. В этом случае работа в представлении будет удобно вестись с сущностью, а не набором значений. Практически данный способ почти решает все вопросы. Вот только не знаю, как можно получить сразу выборку уже готовых объектов с локализованными значениями, минуя лишний слой, где будет осуществляться обновление сущностей строковыми локализованными значениями. В идеале было бы здорово что-то типа такого (на основе сущности Country с полем value, обозначенным как @Transient): Код: plsql 1. Как сделать? 2. Совместить приведенные вначале способы, но Resource Bundle привязать не к properties-файлам, а к БД, причем, к NoSQL-базе, скажем, MongoDB. Из того, что я посмотрел и почитал (опыта практической работы с NoSQL и непосредственно MongoDB нет), получение, да и вся работа с базой, базируется на JSON-представлении как запросов, так и данных, что уже само по себе достаточно близко по духу к веб-проекту. Идея совершенно гипотетическая, исследования в эту сторону не проводились, а курочить текущий проект для "попробовать" не очень хочется, поэтому общараюсь тут с вопросами: есть ли подобный опыт? нормально ли будут "вести себя" SQL-база и NoSQL-база в одном проекте, не сопряжено ли это с трудностями и проблемами? есть ли опыт настройки Spring'овского Resource Bundle на БД (и, в частности, на NoSQL БД)? - кстати, не нашел в пакетах Spring похожих по смыслу классов, как с этим обстоят дела? Буду признателен за ответы и советы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2012, 16:13:56 |
|
||
|
Локализация веб-проекта (БД, взаимодействие)
|
|||
|---|---|---|---|
|
#18+
не вникая в тонкости.. хранить в таблице в виде дерева язык - термины на языке - место термина вводишь новое место -во всех языках появляется пустое место - его и заполняешь. одна таблица, число языков и терминов не ограничено легко формализуется для добавления и извлечения ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2012, 22:13:50 |
|
||
|
Локализация веб-проекта (БД, взаимодействие)
|
|||
|---|---|---|---|
|
#18+
1 вариант реализовал. Правильным было направление, ошибочна реализация, поэтому сразу не получилось. Очень удобно и можно убрать из ДАО методы работы непосредственно с локализованными значениями - они теперь будут вставляться при выборке сущностей. Но столкнулся с такой проблемкой ... Применительно к рассматриваемому примеру со страной: допустим, есть сущность Address, у которой есть поле Country country (ManyToOne). Выбираем определенный address. Естественно, у объекта address.getCountry() Transient-поле localizedTitle (которое я использую для временного хранения локализованного значения из зависимой таблицы CountryTitle) равно null, так как оно не персистентное и автоматом не заполняется. Так вот, вопрос заключается в том, как наиболее правильно и оптимально сделать автоматическую выборку при подобных запросах, когда надо зависимый объект переназначить, заполнив нужное поле значением? - Можно, конечно, для каждого метода прописывать по нисходящей заполнение всех объектов, но уж больно огромными станут запросы, а их много - дурной труд. А если надо вставить метку в 5 зависимых объектов? - тысячи символов в запросе ... Можно использовать @Formula, но если выборка приличная по размерам, то делать подстановку каждому объекту RequestContextUtils.getLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()).toString() - это как-то неправильно: POJO - модель, а это выражение - часть контроллера, засорять структуру не хочется, да и лишних вычислений навалом. Есть ли грамотный выход? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.12.2012, 03:19:48 |
|
||
|
Локализация веб-проекта (БД, взаимодействие)
|
|||
|---|---|---|---|
|
#18+
Провел анализ наиболее часто используемых решений (не путать с оптимальными!, так как понятия не взаимоисключающие) и пришел к выводу, что акцент ставится на нескольких аспектах, применительных к массовому веб-проекту: - любая база фактически должна стать хранилищем изолированных хранилищ "ключ-значение"; - исключить внешние ключи и JOIN в запросах; - для ориентированного под веб и тем более социального приложения максимально переходить на NoSQL-базы, у которых несоизмеримо упрощается горизонтальное масштабирование, а также значительно быстрее работает запись; - подключать системы кеширования (судя по использованию, лидируют memcashed и Redis); - не придумывать велосипеды с полнотекстовыми поисками в базе и тем более не использовать встроенные - специализированные проекты типа Sphinx, Solr и прочие справляются с этим несоизмеримо лучше лучше (включая лексемные нюансы). Проделанный анализ, к сожалению, подталкивает к неутешительным выводам: - резко уменьшается роль RDBMS (если и вовсе не уходит) - вижу разве что для реализации дерева зависимостей, хотя и это расплывчато; - сходит на нет удобство ORM, точнее, уход от универсального и удобного Hibernate к специализированным проектам; - красивое и удобное программирование жертвуется в угоду производительности и скорости, превращая изящную структуру в банальное прокидывание данных из базы клиенту и наоборот. Такие вот неутешительные выводы ((((. От небольшого специализированного вопроса перешел к переосмыслению всего проекта в целом, так как при росте аудитории все равно прийдется менять рельсы ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2012, 17:58:52 |
|
||
|
Локализация веб-проекта (БД, взаимодействие)
|
|||
|---|---|---|---|
|
#18+
исключить внешние ключи и JOIN в запросах; Неоднократно встречал этот (ошибочный) совет. Посмотрите http://docs.oracle.com/cd/E11882_01/server.112/e16638/data_acc.htm#i12132 если вам интересен этот вопрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.12.2012, 19:49:19 |
|
||
|
Локализация веб-проекта (БД, взаимодействие)
|
|||
|---|---|---|---|
|
#18+
Спасибо, интересен. Все на эту тематику интересно. Что до ошибочности - согласен, с идеологической стороны - полный бред. Но есть практика ... Перечитал построение баз и работы полтора десятка крупнейших соцсетей - ВЕЗДЕ придерживаются такого правила, вне зависимости от ЯП, платформы и БД. Кстати, перестроил работу БД - улучшения явные, не так удобно пользоваться всем и сразу, но универсализация общей работы и интернационализации налицо. Позже добавлю еще NoSQL-БД. И явно начинаю понимать почему они идут по такому пути - глупый подход, но зато он решает массу проблем, в основном архитектурных, и, как следствие, - материальных. Мне, конечно, рановато об этом думать, но "плох тот солдат ..." ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.12.2012, 23:50:23 |
|
||
|
Локализация веб-проекта (БД, взаимодействие)
|
|||
|---|---|---|---|
|
#18+
авторЧто до ошибочности - согласен, с идеологической стороны - полный бред. Но есть практика Оракл можно попросить, чтобы он связанные записи в master и details таблицах хранил в одном блоке жесткого диска. Таким образом, никакой нужды в самодельной денормализации нет. При этом, перейти к какому-то другому способу хранения данных на диске (оптимизированному под другие запросы) можно одной командой alter table. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2012, 01:08:13 |
|
||
|
Локализация веб-проекта (БД, взаимодействие)
|
|||
|---|---|---|---|
|
#18+
авторПеречитал построение баз и работы полтора десятка крупнейших соцсетей - ВЕЗДЕ придерживаются такого правила, вне зависимости от ЯП, платформы и БД. В соцсетях, по-моему, выгоднее все партиционировать по дате создания. В противном случае, чтобы показать профайл пользователя, придется читать с диска его посты и коменты трехлетней давности, которые никому уже неинтересны. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2012, 01:14:03 |
|
||
|
Локализация веб-проекта (БД, взаимодействие)
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪВ соцсетях, по-моему, выгоднее все +1 соцСети и Учётка - совершенно разная архитектура хранилища. IDVsbruckакцент ставится на нескольких аспектах, применительных к массовому веб-проекту: сабж вроде про локализацию _сайта_, а не массовый веб проект. Если убрать локализацию - то нет проблем? Так что сравнивать РДБМС и ООБД ещё рано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2012, 09:42:17 |
|
||
|
Локализация веб-проекта (БД, взаимодействие)
|
|||
|---|---|---|---|
|
#18+
Да, ты прав ... вопрос как бы перетек с одного в другое. Хотя на самом деле это я его сначала так сформулировал, так как видел проблему реализации только в той части, которая касалась локализации - структура всего остального вроде не представляла проблемы. Однако в процессе "раскрутки" вопроса все свелось немного к другому. А так как при решении задачи пришлось начитаться всякого, то решение я нашел именно в таком подходе. Заканчиваю переносить сделанное на новые рельсы и пока не жалею. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2012, 19:27:33 |
|
||
|
|

start [/forum/topic.php?desktop=1&fid=59&tid=2130293]: |
0ms |
get settings: |
16ms |
get forum list: |
16ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
41ms |
get topic data: |
17ms |
get forum data: |
4ms |
get page messages: |
58ms |
get tp. blocked users: |
2ms |
| others: | 273ms |
| total: | 437ms |

| 0 / 0 |
