Drizzle | 고유하고 대소문자 구분 없는 이메일 처리
This guide assumes familiarity with:

PostgreSQL

Drizzle에서 PostgreSQL의 고유하고 대소문자를 구분하지 않는 email 처리를 구현하려면, 소문자로 변환된 email 컬럼에 고유 인덱스를 생성할 수 있습니다. 이렇게 하면 대소문자에 관계없이 email이 고유함을 보장할 수 있습니다.

Drizzle은 간단하고 유연한 API를 제공하여 SQL과 유사한 구문을 사용해 이러한 인덱스를 쉽게 생성할 수 있습니다:

schema.ts
migration.sql
import { SQL, sql } from 'drizzle-orm';
import { AnyPgColumn, pgTable, serial, text, uniqueIndex } from 'drizzle-orm/pg-core';

export const users = pgTable(
  'users',
  {
    id: serial('id').primaryKey(),
    name: text('name').notNull(),
    email: text('email').notNull(),
  },
  (table) => [
    // uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
    uniqueIndex('emailUniqueIndex').on(lower(table.email)),
  ],
);

// custom lower function
export function lower(email: AnyPgColumn): SQL {
  return sql`lower(${email})`;
}

lower 함수를 사용하여 email로 사용자를 조회하는 방법은 다음과 같습니다:

import { eq } from 'drizzle-orm';
import { lower, users } from './schema';

const db = drizzle(...);

const findUserByEmail = async (email: string) => {
  return await db
    .select()
    .from(users)
    .where(eq(lower(users.email), email.toLowerCase()));
};
select * from "users" where lower(email) = 'john@email.com';

MySQL

MySQL에서는 문자열 비교를 위한 기본 콜레이션(collation) 설정이 대소문자를 구분하지 않습니다. 이는 SQL 쿼리에서 문자열을 검색하거나 비교할 때 문자의 대소문자가 결과에 영향을 미치지 않는다는 의미입니다. 그러나 콜레이션 설정은 다양하게 변경될 수 있고 대소문자를 구분하도록 구성될 수 있기 때문에, 소문자로 변환된 email 컬럼에 고유 인덱스를 생성하여 대소문자에 관계없이 email이 고유함을 명시적으로 보장합니다.

Drizzle은 간단하고 유연한 API를 제공하여 SQL과 유사한 구문을 사용해 이러한 인덱스를 쉽게 생성할 수 있습니다:

schema.ts
migration.sql
import { SQL, sql } from 'drizzle-orm';
import { AnyMySqlColumn, mysqlTable, serial, uniqueIndex, varchar } from 'drizzle-orm/mysql-core';

export const users = mysqlTable(
  'users',
  {
    id: serial('id').primaryKey(),
    name: varchar('name', { length: 255 }).notNull(),
    email: varchar('email', { length: 255 }).notNull(),
  },
  (table) => [
    // uniqueIndex('emailUniqueIndex').on(sql`(lower(${table.email}))`),
    uniqueIndex('emailUniqueIndex').on(lower(table.email)),
  ]
);

// custom lower function
export function lower(email: AnyMySqlColumn): SQL {
  return sql`(lower(${email}))`;
}
IMPORTANT

함수형 인덱스는 MySQL 버전 8.0.13부터 지원됩니다. 올바른 구문을 위해 표현식은 괄호로 감싸야 합니다. 예: (lower(column)).

lower 함수를 사용하여 email로 사용자를 조회하는 방법은 다음과 같습니다:

import { eq } from 'drizzle-orm';
import { lower, users } from './schema';

const db = drizzle(...);

const findUserByEmail = async (email: string) => {
  return await db
    .select()
    .from(users)
    .where(eq(lower(users.email), email.toLowerCase()));
};
select * from `users` where lower(email) = 'john@email.com';

SQLite

Drizzle에서 SQLite의 고유하고 대소문자를 구분하지 않는 email 처리를 구현하려면, 소문자로 변환된 email 컬럼에 고유 인덱스를 생성할 수 있습니다. 이렇게 하면 대소문자에 관계없이 email이 고유함을 보장할 수 있습니다.

Drizzle은 간단하고 유연한 API를 제공하여 SQL과 유사한 구문을 사용해 이러한 인덱스를 쉽게 생성할 수 있습니다:

schema.ts
migration.sql
import { SQL, sql } from 'drizzle-orm';
import { AnySQLiteColumn, integer, sqliteTable, text, uniqueIndex } from 'drizzle-orm/sqlite-core';

export const users = sqliteTable(
  'users',
  {
    id: integer('id').primaryKey(),
    name: text('name').notNull(),
    email: text('email').notNull(),
  },
  (table) => [
    // uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
    uniqueIndex('emailUniqueIndex').on(lower(table.email)),
  ]
);

// custom lower function
export function lower(email: AnySQLiteColumn): SQL {
  return sql`lower(${email})`;
}

lower 함수를 사용하여 email로 사용자를 조회하는 방법은 다음과 같습니다:

import { eq } from 'drizzle-orm';
import { lower, users } from './schema';

const db = drizzle(...);

const findUserByEmail = async (email: string) => {
  return await db
    .select()
    .from(users)
    .where(eq(lower(users.email), email.toLowerCase()));
};
select * from "users" where lower(email) = 'john@email.com';