Лучшая практика хранения языков в базе данных

Сейчас я работаю над проектом для университета. В основном задача заключается в реализации базового инструмента управления библиотекой (на Java, с использованием Spring Framework и Java Persistence API). Часть требований к программному обеспечению состоит в том, чтобы иметь возможность добавлять и изменять записи книг и сохранять их в базе данных. Книга имеет несколько свойств (название, дата публикации, ...), а также определенный язык. Теперь мой вопрос: как мне (аккуратно) реализовать всю эту концепцию «языка»? Я придумал несколько идей, каждая из которых имеет свои преимущества и недостатки:

Идея 1:

  • Пользовательский ввод: обычное текстовое поле
  • База данных: хранить язык в виде строки (как атрибут отношения book)
  • Плюсы: очень просто реализовать
  • Минусы: языки могут быть неоднородными ("английский", "en", "английский", "АНГЛИЙСКИЙ", ...), много места для человеческих ошибок (опечатки, ...)

Идея 2:

  • Пользовательский ввод: раскрывающийся список / поле со списком
  • База данных: предопределенное языковое отношение, содержащее все возможные языки (например, language_id в качестве внешнего ключа в отношении book)
  • Плюсы: языки унифицированы (например, «английский», «немецкий», «итальянский», ...), мало места для человеческой ошибки.
  • Минусы: каков набор всех возможных языков? Следует/можно ли исключить некоторые языки? Это перебор? Слишком много накладных расходов? Какой формат языков следует использовать (удобочитаемый: «английский», «английский» или более компактный: «en», «en-us», ...)?

Идея 3:

  • Пользовательский ввод: раскрывающийся список / поле со списком
  • Исходный код: как в идее 2, но теперь жестко закодированы все возможные языки как перечисления в исходном коде.
  • База данных: преобразуйте конкретное перечисление в строку или порядковый номер и используйте его в качестве атрибута в отношении book
  • Плюсы: плюсы Идеи 2 + отсутствие жесткого кодирования языковых строк в исходном коде (от if language = "english" до if language = Language.ENGLISH)
  • Минусы: минусы идеи 2 + как перечисления сопоставляются с базой данных (строка, порядковый номер, отдельное отношение)? Перечисления и языки в базе данных должны быть "синхронизированы".

Для меня идея 2 может быть «наиболее разумной», но я все еще не уверен, действительно ли это «хороший» подход. Может быть, вы можете помочь мне.

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

Ole V.V. 13.12.2020 05:44
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
1
1 335
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Отделите представление от бизнес-логики.

Используйте стандартизированный языковой код для внутренней бизнес-логики и хранения данных. У вас есть выбор из нескольких. Я бы выбрал код, используемый Java в классе Locale, если это соответствует потребностям вашего домена. Например, en для английского и fr для французского.

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

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

Получите массив всех известных Locale объектов, вызвав Locale.getAvailableLocales. Зациклите их, чтобы сделать Set, чтобы создать отдельный список языковых кодов.

Или позвоните Locale.getISOLanguages ​​, чтобы получить список всех двухбуквенных языковых кодов, определенных в ISO 639-1. Класс Locale также предлагает трехбуквенный код языка ISO 639-2. Я тут не спец, поэтому разницы не знаю. Но мы можем видеть этот список из 3 и 2 буквенных кодов, определенных ISO 639-1 и 639-2.

Чтобы получить локализованное название языка, передайте предпочтительный объект локали пользователя в метод Locale::getDisplayLanguage.

String displayNameOfFrenchLanguageForJapaneseUser = Locale.FRENCH.getDisplayLanguage( Locale.JAPAN ) ;

displayNameOfFrenchLanguageForJapaneseUser = フランス語

И для немецкого пользователя.

String displayNameOfFrenchLanguageForGermanUser = Locale.FRENCH.getDisplayLanguage( Locale.GERMAN );
System.out.println( "displayNameOfFrenchLanguageForGermanUser = " + displayNameOfFrenchLanguageForGermanUser );

displayNameOfFrenchLanguageForGermanUser = Französisch

Что касается определения перечислений, Enum определяется во время компиляции. Enum нельзя переопределить с дополнительными или меньшими элементами во время выполнения. Напротив, локали и языковые коды время от времени меняются. При обновлении вашего развертывания с помощью другой версии Java могут измениться известные локали. Так что я бы склонялся к мягкому кодированию. Если ваш домен относится к определенному количеству языков, которые вряд ли изменятся, скажем, к романским языкам Западной Европы, тогда может подойти жесткое кодирование с перечислением.

Если вам нужно отслеживать диалекты, а не просто общие языки, такие как квебекский французский по сравнению с французским в целом, вы можете узнать о Common Locale Data Repository (CLDR) , который теперь поставляется с реализациями Java, созданными на основе OpenJDK .

Другие вопросы по теме