Многоязычность.. Как лучше?

alexhemp

Новичок
Про вас речь вообще не идет. Речь идет об авторе топика.

Вы дали совет, а потом сами признали что он не лучший.

Мне вообще все равно что Вы или автор топика используете - сделаете неверно - меньше конкуренция :)

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

tf

крылья рулят
alexhemp можеш скажеш у тебя реализована мноязычность?
 

DruidM

Новичок
alexhemp
Напишите, пожалуйста, почему добавлять новый язык, как новую колонку в таблицу - плохо?
И чем предложенный Вами вариант - лучше варианта
vadim.
Ответ вроде: "потому что это противоречит четвертой нормальной форме" считается отмазкой, так как на практике часто жертвуют правильностью в обмен на скорость.
 

Гриша К.

Новичок
Скажите пожалуйста, а вот к примеру кода пользователь выбирает английский язык, или немецкий, или французский, в этом случае какую кодировку надо использовать.
Сейчас у меня стоит кодировка по умолчанию windows-1251.

Английский язык в такой кодировке у меня просматривается нормально, но вот хотел узнать нужно ли менять кодировку, для каждого языка.
 

vadim

Guest
Гриша К.
Мы используем UTF-8, тогда нигде не надо менять кодировки.
windows-1251 для русского и английского достаточна
Другие кодировки уже зависят от тех языков, которые вы выбрали
 

Гриша К.

Новичок
vadim, спасибо за разъяснение. Тогда пока можно не беспокоится.
У меня часть информации храниться в БД на 2-х языках, соответственно поиск осуществляется по 2-м языкам.
Текст навигации и совсем чуть чуть содержания в файле (Для 2-х языков 2-файла).
Я почему это написал, просто я не совсем понял по поводу кодировки UTF-8, и решил что может быть это в базе она так храниться, но значит с файлами мне так не сделать.
И просто в броузере я выбрал такую кодировку и вижу иероглифы, вот и непонял вас поп оводу кодировки UTF-8.
 

alexhemp

Новичок
tf
Расскажу, отчего не рассказать.

DruidM
Структура БД - это не то чем программа не должна оперировать, программа должна оперировать ДАННЫМИ а не менять их СТРУКТУРУ - т.е. МОДЕЛЬ ПРЕДМЕТНОЙ ОБЛАСТИ.
Область же не меняется - почему вы тогда хотите менять модель?

Многоязычность на сайте реализовать несложно. Сперва нужно определить, что же такое "язык".

Для этого служит справочник lang

В нем есть атрибуты
LANG_ID - идентификатор языка - суррогатный ключ
NAME - название языка (English, Russian ....)
ISO_CODE - ISO код языка
LOCALE - PHP локаль для данного языка (чтобы работали стандартные строковые ф-ции)
CHARSET - кодовая таблица языка
Ну и плюс несколько вспомогательных полей (флаг "язык сайта по умолчанию", номер языка в списке, список доменов для определения языка по домену)

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

Например объект типа "Новость".

Языко-независимые атрибуты

NEWS_ID - идентификатор, суррогатный ключ
DT - дата-время новости
USER_ID - идентификатор "владельца" для записи

Языко-зависимые атрибуты

NEWS_ID + LANG_ID - первичный ключ
TITLE - заголовок
CONTENT - содержание
STATUS - статус новости

Очевидно что для вывода одной новости на одном языке нужно все-навсего сделать простой JOIN.

Очевидно так-же что для добавления нового языка - достаточно добавить одну запись в таблицу lang - ну и соотв. тексты на нужном языке.

Ответ вроде: "потому что это противоречит четвертой нормальной форме" считается отмазкой, так как на практике часто жертвуют правильностью в обмен на скорость.
Можешь считать как угодно - я уже написал - больше дураков, меньше конкуренция. "Скорость" бывает разная. Скорость выполнения запросов у данных методов - неразличима. И в том и в другом можно по дурацки все сделать, если руки растут не оттуда. А вот "скорость" отыскания потом багов и решения новых поставленных задач в моем методе на порядки выше просто потому что данные изначально нормализованы. Представь себе сайт с десятком языков - и сразу будет понятно.

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

Как можно видеть - статус находиться в языко-зависимом блоке, а это значит что каждая языковая версия может жить своей жизнью, например новость на русском опубликовали вчера, а на английский переведут только на след. день - когда переводчик придет на работу.
Теперь представляем себе что у нас 10 языков и 10 переводчиков - в варианте vadim потребуется ввести 2x10 новых полей в таблицы (а это кстати только замедлит выборку, т.к. длина одной строки резко возрастет).

С разнообразными "надписями" я поступаю аналогично - выношу их в базу в отдельные 2 таблицы. GetText использовать не слишком удобно, т.к. владелец сайта нанимает переводчика, не я.
А переводчик тупо переводит все языковые пары. Для вывода используется smarty и простой ресурс-плугин, так что надписи могут содержать подстановки вида "There are {$rows} rows in table".

Как видите использование кодировок осталось за кадром - потому что к собственно многоязычности они отношения не имеют.
UTF-8 удобен безусловно, но в первую очередь тем, что позволяет забыть о "кодировке" как таковой и унифицировать строковые операции независимо от языка.

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

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

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

Sync

Новичок
Автор оригинала: alexhemp

NEWS_ID - идентификатор, суррогатный ключ
DT - дата-время новости
USER_ID - идентификатор "владельца" для записи

Языко-зависимые атрибуты

NEWS_ID + LANG_ID - первичный ключ
TITLE - заголовок
CONTENT - содержание
STATUS - статус новости
Думаю уместно добавить в таблицу языко-независимых атрибутов еще и поле NEWS_FIRST_INSERTED чтобы не было проблем с переключением между языками просматривая новость, то есть
PHP:
news_id   news_first_inserted 
1               1              // lang_id = 1
2               1              // lang_id = 2
3               3              // lang_id = 1
4               3              // lang_id = 2
А так хорошая модель, тож ее использую.
 

vadim

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

Аминь
 

DruidM

Новичок
alexhemp
Ваш слова да богу в уши :)
Года три назад писал CRM систему. Данные хранились в MS SQL Server 2000. Так вот эта база страдает одним не достатком - при объединении более 5-7 таблиц в одном запросе жутко тормозит и единственный способ ускорить это вводить избыточность данных (благодаря которой, кол-во таблиц сокращается)
И Ваш и пример vadim хорош, для каждого конкретного случая и незная контекста применения решения нельзя говорить о том, что какое-то решение лучше.
В Вашем примере можно в таблицу языко-независимую добавить еще и поле STATUS, если необходимо, чтобы разноязычные версии сайта были одинаковые. Т.е. после перевода новости на все языки, только тогда отображать пользователю.
PS: добавление нового языка это редкое явление и в некоторых проектах это действо можно считать изменением модели.

PSS: увеличение кол-во столбцов не замедляет выборку по отношению к объединению и доп. условию на язык.
Проверить достаточно просто :) нужно сделать замеры или посмотреть Explain запроса.

PSSS: маленькая описка:
Структура БД - это не то чем программа не должна оперировать
.
С этой опиской полностью согласен, программа должна оперировать со всем, что может позволить выполнить ее предназначение.
По поводу структуры, есть программы - генераторы программ, например проект Муромец. Эти программы оперируют и со структурой и с данными.
 

alexhemp

Новичок
DruidM

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

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

Проблемы с JOIN в MS SQL никогда не испытывал, лет 10 назад писал процедурки с десятком джойнов на MSSQL 6.5 - все летало, на больших для того времени базах. Вероятно следует изучить - почему это проиходило и оптимизировать структуру данных.

Увеличение числа СТРОКОВЫХ столбцов может замедлить выборку, если они переменной длинны.
Во первых одна строка таблицы зачастую перестает помещаться на одну страницу файла БД. Во вторых - переход к следующему ряду будет требовать анализа текущего ряда, вместо простого прибавления смещения.

В общем господа повторю - не хотите слушать советы - делайте как считаете нужным - МЕНЬШЕ БУДЕТ КОНКУРЕНЦИЯ.
Хотите писать масштабируемые программы - изучайте теорию построения БД, она рулез.

-~{}~ 26.03.06 13:42:

И Ваш и пример vadim хорош, для каждого конкретного случая и незная контекста применения решения нельзя говорить о том, что какое-то решение лучше.
Вы это зачем написали? Контекст обозначен в названии топика. Если вы не знаете что лучше - не пишите что все хорошо.

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

добавление нового языка это редкое явление и в некоторых проектах это действо можно считать изменением модели.
Когда пишут систему иногда неизвестно какие вообще языки будут использоваться. Может вополне оказаться что это будет китайский, английский и немецкий.
Адаптация при первичной инсталляции в моей системе выполняется за 2 минуты - формированием списка языков.
 

DruidM

Новичок
Ваше мнение понятно.
Заметьте, я не говорил, что реляционную теорию знать не нужно. Я всего лишь сказал, что ее, как и любую теорию нужно использовать разумно! И как Вы правильно заметили, не нужно заколачивать гвозди микроскопом :)
PS: лет 10 назад был 1996 год и в ходу были 286 и 386 компы, только появлялись 4-ки. Скорее всего Вы немного лукавите, говоря о 10 JOINах и достаточном(млн.? 2млн.?) объеме данных :)
 

baev

‹°°¬•
Команда форума
лет 10 назад был 1996 год и в ходу были 286 и 386 компы, только появлялись 4-ки
Вас обманули.
Воспользуйтесь поиском — в каком году первые «пентиумы» были выпущены?
(Лично у меня в 1996 рабочим компом был «пентиум»-100.)
 

alexhemp

Новичок
DruidM

У меня был Windows NT Server 4.0 На Pentium 133 с 64 мегами памяти. База была - для системы автоматизации сети заправочных станций. Аналитических отчетов там было много, они тягали кучу справочников, помимо основных JOIN-ов.

Заметьте, я не говорил, что реляционную теорию знать не нужно. Я всего лишь сказал, что ее, как и любую теорию нужно использовать разумно!
В первую очередь - ее использование - это само по себе разумно. А выделять по полю на язык - не разумно.

Кстати еще пример хороший для ущербности использования специализированных полей для языка - напишите хранимую процедуру которая в качестве параметра принимает "язык", например "en" и возвращает данные только на заданном языке.
Напишите триггер на такую таблицу, которая будет в зависимости от того, на каком языке изменилась запись создавать в другой таблице сообщение на этом языке (например это может быть очередь уведомлений клиентам о поступлении товара на склад).
Это все приведет вас к очевидной проблеме наличия EVAL-о подобной ф-ции в вашем SQL-сервере. Переносимость такого решения будет нулевая. Масштабируемость тоже - близкая к нулевой.
 

Kelkos

Сам себе программер
Хех.. как много копий сломано о многоязычность. На мой взгляд - суета на пустом месте. А что если многоязычность - это частный случай мультисайтовости. И потом, на практике столкнулся, что чаще нужна разная структура сайтов в каждом языке.
Не буду раводить теоритическую бодягу.. на мой взгляд лучше сделать грамотную мультисайтовость, чем ипаться с мифической многоязычностью. В мультисайтовую модель мы можем вписать языковые варианты, а наоборот - нет.
На вопрос - как? А вот так - (самый тупой вариант)
ru.my-site.com - русский
en.my-site.com - engl.
Переключение с языка на язык ещё проще. .т.к. наверняка будет юзаться модеврайт, то переходим на домен нужного языка в тотже каталог. Типо, с ru.my-site.com/cat/ переходим в en.my-site.com/cat/ .. если такой страницы нет, то на главную или ещё куда (сами придумайте).
не бойтесь сделать много джойнов
с недавних пор боюсь..
 

DruidM

Новичок
не сочтите за флуд

Автор оригинала: alexhemp
В первую очередь - ее использование - это само по себе разумно. А выделять по полю на язык - не разумно.
...
Это все приведет вас к очевидной проблеме наличия EVAL-о подобной ф-ции в вашем SQL-сервере. Переносимость такого решения будет нулевая. Масштабируемость тоже - близкая к нулевой.
В школе у меня была хорошая учительница математики и она расказала нам одну историю:
Как-то, на урок 8-го класса приходит аспирант, мой ученик. Я его со всеми познакомила и предложила ему и классу провести эксперимент. Задала задачку для класса и для него из учебника олимпиадных задач (сложность **).
И аспирант, и один из учеников ее решили, только решение аспиранта занимало целую страницу, а решение ученика всего 4 строчки.

К чему это все я расказал? Часто чем больше работаешь над маштабными проектами, то и на простые пытаешься перенести те же решения, но иногда лучше для простого проекта - простое решение.

PS: видел один проект, в котором даже хранимки создавались автоматически при небольшом изменении бизнес-логики.
Иногда вообще лучше названия на разных языках хранить в файлах и подключать нужный в момент.
PSS: предлагаю поставить точку в нашей дискуссии, так как она переростает в спор, что не есть хорошо. alexhemp
Ваша позиция мне ясна и понятна.
 

tf

крылья рулят
Автор оригинала: alexhemp
Языко-независимые атрибуты
Языко-зависимые атрибуты
интересная идея. надо ее у себя тоже реализовать.
будет четкая сзявание информации на разных языках
пока что у меня одна таблица id,lang,данные

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

kvf77

Red Devil
А FAQ меж тем заработало, а никто так и не глянул

Создание многоязычных приложений:
http://phpclub.ru/faq/wakka.php?wakka=multilang&v=9vm

Еще одна моя статья:
Многоязычные приложения. Способы хранения динамических данных:
http://php.russofile.ru/ru/authors/multilangual/dynamic/

Про GetText:
http://php.russofile.ru/ru/authors/multilangual/php_gettext_prof/

CORSAiR
специально для тебя замечание - хамить мне не стоит
 

CORSAiR

Новичок
Автор оригинала: kvf77
специально для тебя замечание - хамить мне не стоит
Хамить? Где ты увидел хамство в ссылке на правила форума ?

P.S. а вот фразу " для таких как ты" в употребленном контексте считаю хамством..

-~{}~ 27.03.06 17:58:

Спасибо всем за ответы! Очень помогли!
 

kvf77

Red Devil
CORSAiR

такие как ты - не сталкивающиеся ранее с проблемой - если ты видишь во всем хамство - это твои проблемы

к тому же ты не уммешь читать FAQ, которые для тебя составлены (на момент написания твоего поста оно работало - это ттак, чтобы присечь возражения)
 
Сверху