Создание базы данных перевода строк для нескольких (собственных) проектов

9

В нашей компании есть таблица перевода ms-sql, в которой хранятся такие строки:

Id |     Key     | Language | Value 
 1 | hello-world |  nl-BE   | Hallo Wereld
 2 | hello-world |  en-GB   | Hello World

В системе 3 языка, и я ожидаю, что в будущем их число возрастет до 10.

Эта таблица читается несколькими очень разными проектами (около 60 проектов, в основном веб-сайты / веб-приложения и некоторые веб-сервисы), каждый из которых открывает соединение базы данных с базой переводов, кэширует переводы

Обратная связь от разработчиков переднего плана заключается в том, что наш пользовательский интерфейс для ввода или изменения самого большого недостатка переводов заключается в том, что они не могут знать, какой проект использует какие строки.

Иногда они изменяют строки, не зная, что они нарушают 7 проектов.

Теперь им просто нужно что-то напечатать, this.Translate("Hello World")а система позаботится обо всем остальном.

Я, конечно, мог бы заставить их что-то вроде, this.Translate("Hello World","AwesomeApplication1")но кажется, что это потребует довольно много рефакторинга во многих многих проектах.

Как бы вы пошли о предоставлении этого решения? Как бы вы, как разработчик, предоставили «название проекта» для перевода? Как бы вы сохранили это в базе данных?

Важное примечание: повторное использование перевода - это и есть смысл централизованной базы данных, так что можно переводить переводы в один проект

1|hello-world|nl-BE|Hallo Wereld|MyAwesomeApplicatoin1
5|hello-world|nl-BE|Hallo Wereld!|MyAwesomeApplicatoin2

это не совсем нужный вариант.

Я бы предпочел что-то вроде:

1|hello-world|nl-BE|Hallo Wereld|MyAwesomeApplicatoin1,MyAwesomeApplicatoin2

или эквивалент внешнего ключа, просто помещая имена в таблицу.

ОБНОВИТЬ

Основываясь на совете нормализовать базу данных, я до сих пор придумал что-то вроде этого:

//this allows me to distinquish if translations where added by developer or by translator

ОБНОВЛЕНИЕ2: добавлено edmx вместо текста. Если кому-то интересно, я мог бы заняться проектом WCF, я включаю эту концепцию, чтобы другие люди могли ее протестировать и использовать.

Mvision
источник
Ты для нормализации. проголосовали за и а. Я верю, весенний java github поможет.
tgkprog

Ответы:

5

Предварительное примечание № 1: Вы не говорите нам, как переводы поддерживаются в настоящее время

Предварительное примечание № 2: Ваша база данных не нормализована. Какое бы решение вы ни выбрали, сначала нормализуйте базу данных . Вы столкнетесь с ужасными проблемами обслуживания позже, если вы не сделаете этого сейчас

Это то, что я бы сделал.

  1. Перепишите ваш переводящий вызов так, чтобы он переносил идентификатор программы обратно на сервер

  2. Внутренний переводчик поместит строку в таблицу базы данных, если она еще не существует, и пометит ее идентификатором программы.

  3. Если строка уже существует, она будет обновлена ​​только в том случае, если идентификатор программы совпадает с исходным идентификатором программы, с которой была создана строка. Если нет, верните уведомление о конфликте.

Варианты:

  • Вы можете использовать «идентификатор разработчика / идентификатор переводчика» вместо идентификатора программы. Я считаю это лучше, потому что есть люди, которые знают иностранный язык, и те, которые думают, что они знают. Только первая группа имеет права на изменение.

  • Возможно, вы захотите сохранить идентификаторы всех программ, которые используют строку в БД, чтобы вы знали, какие программы конфликтуют.

  • Вы можете распространить эту концепцию «владения» на каждый отдельный язык: один человек может говорить по-английски, а другой - по-голландски.

  • Как только ваша база данных нормализуется, вы добавляете сложность сборки, такую ​​как «Программа A на языках 1,2,3; B на 3 и 5»

Я также предлагаю вам написать отдельную программу поддержки переводов, которая покажет вам пропущенные переводы и т. Д. Я однажды сделал это с двухуровневой авторизацией: каждый перевод должен проверяться вторым человеком (обычно носителем языка).

Ян Догген
источник
1
Я обновил свой вопрос, основываясь на ваших идеях
Mvision
5

Поскольку они ссылаются на «this» ... вы можете присвоить имя проекта «this» один раз (например, через конструктор), и интерфейс для функций перевода для кодировщиков не изменится. Под капотом он просто добавляет имя проекта в запрос к базе данных. В качестве альтернативы, вы можете предоставить «this» способ узнать название проекта самостоятельно. Это действительно будет зависеть от того, как у вас структурированы ваши классы.

Для хранения вы можете сделать что-то вроде:

1 ! hello-world ! nl-EN ! Hello World  ! *
2 ! hello-world ! nl-EN ! Howdy, World ! CowboyApp
3 ! hello-world ! nl-EN ! Arrgh        ! PirateApp

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

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

GrandmasterB
источник
Идея переместить его в класс «this» мне кажется хорошей, я думаю, что я собираюсь переместить имя проекта в файл web / app.config и прочитать его оттуда. Как вы думаете, идея подстановочных имен / имен проектов масштабируется до 4000 переводов?
Mvision
3
В качестве усовершенствования можно добавить триггер к базе данных или DBAL, который обновляет столбец «подписанные программы» всякий раз, когда переведенное слово читается.
Как триггер базы данных может узнать имя проекта? (Мы используем Entity Framework 4)
Mvision
@ Mvision Я не понимаю, почему нет - объем не должен быть большой проблемой. Если во многих специфичных для приложения переводах просто вставляется имя приложения, вы также можете использовать константы для сокращения дублирования.
GrandmasterB
я неправильно понял. да, триггер мог бы сработать и ускорить процесс по сравнению с проверкой и обновлением этого материала через EF при чтении ... хороший вызов
Mvision
1

Если все ваши проекты написаны на C #, и все вызовы переводчика выглядят так

this.Translate("hello-world")

где «hello-world» является ключом в вашей таблице перевода, не должно быть слишком сложно написать небольшой сканер исходного кода, используя регулярные выражения, чтобы найти все вызовы переводчика и назначить ключевым словам соответствующие имена проектов. Таким образом, вам не нужно менять какой-либо из существующих интерфейсов кода или переводчика.

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

Док Браун
источник
Мне нравилось такое решение. Но это потребует, чтобы все 60 проектов (некоторые даже не мои) были полностью протестированы перед началом производства с этой новой системой. Предлагаемое решение для переноса имени проекта в вызывающий код работает отлично и вызовет гораздо меньше хлопот, в любом случае, спасибо!
Mvision
1
@Mvision: я думаю, что наоборот. Если вы определяете имя проекта для переводов во время выполнения, вы должны удостовериться, что каждая веб-страница с каждым переводом для всех ваших 60 проектов будет вызываться один раз, чтобы убедиться, что вы зарегистрировали их все. Статическое сканирование источника или сборок, однако, дает вам полный список без необходимости каких-либо тестов или запуска всей системы.
Док Браун