Правильный тип для String int double boolean

168
08 февраля 2018, 16:44

Задача стоит в проектировании БД для интернет магазина.

У каждого товара есть набор характеристик (связь многие ко многим разбивается через промежуточную табличку). У сущности "характеристика" есть кроме id еще String name и ??? value

Вопрос в том, какой лучше тип выбрать для value ?? пока склоняюсь к типу String, в который можно писать все вышеперечисленные типы. Еще есть мысли по поводу не заморачиваться и написать туда Object или Serializible.

С точки зрения проектирования какое решение будет правильнее?

Spring Boot (Spring JPA)

Answer 1

Еще есть мысли по поводу не заморачиваться и написать туда Object или Serializible.

А заморочиться придется...

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

  1. Типизация (без него никуда), с основными типами: целое, с плавающей точкой, булевая, дата, строка. Ну может еще что-то.
  2. Реализация типа на уровне класса

Если подробнее то примерно так (простейшая реализация для двух типов строка и целое число):

abstract class MyType {
    abstract void setValue(int value);
    abstract void setValue(String value);
    abstract String getValue();
}
class MyTypeString extends MyType {
   private String valueString=null; 
   @Override
   void setValue(int value) {
        valueString=new StringBuilder().append(value).toString();
   }
   @Override
   void setValue(String value) {
        valueString=value;
   }
   @Override
   String getValue() {
      return value;
   }
}
class MyTypeInt extends MyType {
   private Integer valueInt=null; 
   @Override
   void setValue(int value) {
        valueInt=value;
   }
   @Override
   void setValue(String value) {
        try {
           int val=Integer.parseInt(value);
           valueInt=new Integer(val);
        }
        catch(Exception ex) {
           valueInt=null;
        }
   }
   @Override
   String getValue() {
      return new StringBuilder().append(valueInt).toString();
   }
}
Answer 2

Выбрать "правильнее" не получится, зависит от реализации и необходимых задач. Как вариант, добавить таблицу справочник характеристик, в которой хранить название характеристики и её тип (например Ватт, число), а в самой характеристике хранить переменную с типом Object. В таком случае, когда нам необходимо добавить значение на экран, можно просто воспользоваться .toString(), когда нам необходимо сделать фильтрацию (например, показать для товара ползунок с максимальным и минимальным значением (блок питания 300-1000 Ватт)) используем справочник характеристик и конвертируем значение в нужный формат.

Answer 3

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

Вариант 1
Для каждого типа значений создать отдельную таблицу number_values(товар, характеристика, значение-число), string_values(товар, характеристика, значение-строка) и т.д.

Плюсы:

  • Контроль данных на уровне БД (например, для числовой характеристики в number_values не получится записать строку и пр. мусор).

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

Минусы:

  • Сложный общий SQL-запрос для выборки значений характеристик - нужно делать join-ы с определенной таблицей со значениями в зависимости от типа характеристики.
  • Усложнение логики вставки/обновления/удаления значения характеристики - таблица также определяется в зависимости от типа характеристики (НО, учитывая, что структура таблиц со значениями одинакова, отличается только тип значения, то можно легко написать общий код).
  • Нужно самостоятельно контролировать консистентность данных на предмет того, чтобы, например, по одной и той же характеристике одного товара не было записей в нескольких таблице значений разных типов.

Вариант 2 - использовать одну разряженную таблицу values(товар, характеристика, значение-число, значение-строка, значение-дата, ...), где заполнено только одно из значений.

Плюсы:

  • Значения атрибутов выбираются из одной таблицы -> простой SQL-запрос
  • Для каждого товара не более одного значения любой характеристики

Минусы:

  • Сложность в расширении - необходимо модифицировать общую таблицу со значениями
  • Хранение в одной большой таблице при большом объеме данных станет узким местом

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

READ ALSO
Удаление символа из строки

Удаление символа из строки

Здравствуйте, вот такая проблемаКак из строки удалить символы [], если ] ещё можно удалить, то с [ я не справился

238
В чем ошибка scanner.nextInt();?

В чем ошибка scanner.nextInt();?

Добрый деньРебята, подскажите что здесь не так? Вот ошибка

171
Ошибка cannot find symbol BorderLayout

Ошибка cannot find symbol BorderLayout

Пытаюсь запустить пример использования KeyListener, но компилятор выдает ошибку

184