Использование настраиваемых типов данных
Привет, разработчики 👋. В этой статье я продемонстрирую, как мы можем использовать типы данных UUID и Binary (16) в gorm v2 и golang.
Что такое UUID?
UUID - это всего лишь 128-битное значение, которое обычно представляется в удобочитаемом формате в виде строки UTF8, состоящей из 5 групп шестнадцатеричных символов, разделенных тире.
Пример: cef4c20c-30cf-11eb-9242–9822ef9cf075
Плюсы использования UUID вместо AUTO_INCREMENT PRIMARY KEY?
- Они уникальны для таблиц, баз данных и серверов.
- Их трудно угадать по URL-адресам.
Минусы использования UUID:
- Увеличенное хранилище, то есть 36 символов, и, следовательно, проблемы с производительностью.
- Отладить сложнее.
Для более подробной информации посетите здесь.
Рассматривая как плюсы, так и минусы 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. Надеюсь, это поможет вам в вашем проекте. Любые предложения будут очень ценными. Счастливого кодирования 💻.