Использование настраиваемых типов данных

Привет, разработчики 👋. В этой статье я продемонстрирую, как мы можем использовать типы данных UUID и Binary (16) в gorm v2 и golang.

Что такое UUID?

UUID - это всего лишь 128-битное значение, которое обычно представляется в удобочитаемом формате в виде строки UTF8, состоящей из 5 групп шестнадцатеричных символов, разделенных тире.

Пример: cef4c20c-30cf-11eb-9242–9822ef9cf075

Плюсы использования UUID вместо AUTO_INCREMENT PRIMARY KEY?

  1. Они уникальны для таблиц, баз данных и серверов.
  2. Их трудно угадать по URL-адресам.

Минусы использования UUID:

  1. Увеличенное хранилище, то есть 36 символов, и, следовательно, проблемы с производительностью.
  2. Отладить сложнее.

Для более подробной информации посетите здесь.

Рассматривая как плюсы, так и минусы UUID, мы будем работать с UUID программно в нашей реализации golang и gorm, но мы сохраним его как двоичный (16) в базе данных для большей компактности.

Начнем нашу демонстрацию

Мы будем использовать следующие пакеты.

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
go get -u github.com/google/uuid

Проблема

Поскольку мы будем использовать binary(16) в качестве типа столбца для ID. В gorm нет встроенной поддержки для выполнения запросов для двоичного типа данных. И двоичный файл тоже не в удобочитаемом формате. Таким образом, мы будем использовать UUID для разработки (код gorm и golang), но будем использовать двоичный файл для хранения в базе данных.

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

Реализация настраиваемого типа данных

Давайте кратко обсудим приведенный выше код

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

[Строка 1-2]: Здесь мы создаем новый тип MYTYPE как uuid.UUID.

[Строка 4–8]: StringToMYTYPE - вспомогательная функция для преобразования строкового представления UUID в наш настраиваемый тип данных.

[Строка 19–29]: здесь реализована логика маршалинга и демаршалинга для нашего настраиваемого типа данных.

[Строка 15–18]: GormDataType функция сообщает, какой тип данных будет использоваться во время миграции таблицы. В нашем случае мы хотим binary(16).

[Строка 31–38]: Scan функция сообщает GORM, как получать данные из базы данных. Здесь мы ожидаем []byte от базы данных и конвертируем в uuid.UUID для более легкого использования.

Например

[]byte ➡️ [151 77 149 200 247 16 68 202 171 131 192 137 149 72 249 229]
uuid.UUID ➡️ cef4c20c-30cf-11eb-9242–9822ef9cf075

[Строка 40–43]: Value функция сообщает GORM, как сохранять данные в базе данных. Это обратное преобразование сверху.

Модель

В демонстрационных целях мы создадим две связанные модели с отношением.

A Post has many Comments

Мы создали две модели Post и Comment. Здесь мы использовали UUID_TO_BIN(UUID()) функцию MySQL для генерации binary(16)

UUID()️ ➡️ d15f093b-30d3–11eb-9242–9822ef9cf075

UUID_TO_BIN(UUID()) ➡️ 0xde9dde9330d311eb92429822ef9cf075

База данных

Здесь мы настраиваем соединение MySQL gorm. Мы также автоматически переносим две наши ранее сделанные модели Post и Comment.

Добавление новой записи в базу данных

После создания нового сообщения, если мы напечатаем post.ID, мы получим

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

Здесь мы не получаем фактический идентификатор только что созданного сообщения. Это работает только для столбца автоинкремента в MySQL [я думаю].

В настоящее время мы используем UUID_TO_BIN(UUID()) функцию MySQL для генерации двоичного файла (16). Но теперь мы вручную создадим uuid и вставим его при создании любого нового сообщения с помощью хука BeforeCreate. Эта реализация решит нашу предыдущую проблему, то есть получение недавно созданного идентификатора сообщения.

Хук BeforeCreate

Финальная основная программа

Давайте кратко обсудим этот код

  • [Строка 1–6]: Здесь мы создаем нашу новую запись.
  • [Строка 8–13]: мы получаем идентификатор недавно созданного сообщения, используя post.ID. Затем создайте комментарий к этому сообщению.
  • [Строка 15–18]: Здесь мы демонстрируем where запрос для получения недавно созданного сообщения с его комментарием.

Таблица `posts`

Таблица `комментарии`

ЗАКЛЮЧЕНИЕ

Если вы запутались в какой-либо части, вы можете проверить эти проекты на github.





Это все для этой статьи. Это конец нашего короткого путешествия с реализацией пользовательского типа данных UUID и binary (16) в gorm. Надеюсь, это поможет вам в вашем проекте. Любые предложения будут очень ценными. Счастливого кодирования 💻.