Архитектура базы данных для этого сценария

#architecture #database-design

#архитектура #база данных-проектирование

Вопрос:

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

  • Тип 1: Количество попыток. (например, допускающий запуск 7 раз)
  • Тип 2: Пробная версия (ограничена по времени).
  • Тип 3: Полный

Итак, каждая лицензия должна хранить некоторое пользовательское значение. (Тип 1: целое число, тип 2: дата-время, Тип 3: null)

Какая архитектура является наилучшей для этого сценария?

  • Если я решу поместить все лицензии в одну таблицу, у меня останется по крайней мере 1 неиспользуемый столбец для каждой строки (конечная дата будет равна нулю для типа 1, время выполнения будет равно нулю для конечной даты, и оба будут равны нулю для типа 3):
    LicenseID---LicenseType---CustomerID---EndDate---TryTimes
    С другой стороны, я бы хотел, чтобы мой дизайн был максимально гибким (возможно, в будущем появится больше типов лицензий?)
  • Другим возможным решением было бы использование некоторого подхода, подобного метаданным:
    LicenseID---LicenseDefinition---CustomerID---
    Где LicenseDefinition содержит информацию о типе и ограничении лицензии и анализируется на стороне кода.

Какую из них вы предлагаете использовать более традиционно? Вы предлагаете какой-либо другой способ ее реализации?

ОБНОВЛЕНИЕ: Только что узнал о Sparse столбцах SQL Server. Звучит очень многообещающе…

Комментарии:

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

2. @Andrew: довольно близко к моему второму решению. Почему вы не отправили это в качестве ответа? Пока мой предпочтительный вариант.

Ответ №1:

На первый взгляд (я еще не реализовал ничего подобного), я мог бы сделать что-то вроде этого:

Создайте таблицы базы данных для Customer и License . Внутри Customer , наряду со всей другой общей информацией о клиентах, я бы добавил столбец для licenseType , который был бы reference License таблицей.

License будет хранить licenseId , а также любые соответствующие метаданные. Это не будет включать правила, зависящие от лицензии.

На стороне кода я бы создал LicenseFactory класс, который создавал бы экземпляр лицензионного интерфейса ( ILicense ). ILicense может выглядеть примерно так (в PHP):

 interface ILicense
{
    public isValid($customer);
}
  

Тогда у меня были бы реализации, зависящие от лицензии:

 class TrialLicense implements ILicense
{
    public isValid($customer)
    {
        // business logic for this specific license type here
    }
}
  

Класс factory будет выглядеть примерно так:

 class LicenseFactory
{
    public static function getInstance($type)
    {
        switch($type)
        {
            case 0:
                return new TrialLicense();
                break;
        }
    }
}
  

Итак, теперь мой код приложения может выглядеть примерно так:

 public function isLicenseValid($customer)
{
    return LicenseFactory::getLicense($customer->licenseType)->isValid($customer);
}
  

Ничего из этого не было протестировано, и это всего лишь мои (довольно пространные) первоначальные мысли. Надеюсь, это немного поможет (даже если ваше приложение может не управляться php :))

Редактировать: Забыл упомянуть — преимуществом этого подхода является расширяемость. Каждый раз, когда вы хотите добавить новый тип лицензии, вы просто добавляете новую строку в License таблицу и новую ILicense реализацию с любыми требуемыми бизнес-правилами.

Комментарии:

1. Очень интересный Демиан. Единственное ограничение, которое я вижу, заключается в том, что клиенты не могут иметь более 1 лицензии.

2. Тогда решением было бы создать таблицу CutomerLicense, которая могла бы содержать отношение «один ко многим» (один Cutomer ко многим CutomerLicense)

3. … И, конечно, вам также пришлось бы модифицировать функцию isLicenseValid для обработки нескольких лицензий (на данный момент обрабатывает только одну).

Ответ №2:

Вы должны вести отдельную таблицу для каждого типа лицензии:

 LicenseID(PK)---Type

LicenseID(FK)---EndDate

LicenseID(FK)---TryTimes
  

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

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

Комментарии:

1. По правде говоря, я не уверен почему, но я думаю, что это может ограничить расширяемость. Я просто не чувствую себя правильно по этому поводу. Но, думаю, мне нужно еще подумать. хотя 1 за идею.

Ответ №3:

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

Это первый вариант.

Другим вариантом является использование простой базы данных NoSQL с небольшим объемом памяти или OO базы данных, такой как db4o, или даже простых хранилищ данных, таких как зашифрованный XML файл.