MySql에서 기본값으로 함수를 사용할 수 있습니까?


95

다음과 같이하고 싶습니다.


create table app_users
(
    app_user_id smallint(6) not null auto_increment primary key,
    api_key     char(36) not null default uuid()
);

그러나 이로 인해 오류가 발생합니다. mysql에서 기본값에 대한 함수를 호출하는 방법이 있습니까?

감사.

답변:


130

아니, 할 수 없습니다.

그러나 다음과 같이이를 수행하는 트리거를 쉽게 만들 수 있습니다.

before_insert_app_users TRIGGER 생성
  app_users에 삽입하기 전에 
  각 행
  SET new.api_key = uuid ();

2
@ 기존 행에 UUID를 채우려면 stackoverflow.com/questions/6280789/… 를 참조하십시오.
Sam Barnum

2
이것은 DEFAULT 값을 갖는 것과 완전히 동일하지 않습니다. 값이 NULL 인 경우에만 키를 설정하도록이 대답을 어떻게 변경합니까?
ToolmakerSteve

1
MySQL은 오랫동안 사용되어 왔지만 트리거가없는 열에 대해 기본 UUID를 구현할 수 없습니다. 그 이유는 분명히 MySQL 기본 코드에 여전히 존재하는 1980 년대 기술에 포함되어 있습니다 ( "we ca n't have nice things"검색) : percona.com/blog/2013/04/08/…
RyanNerd

1
@RodolVelasco uuid 함수는 높은 충돌 저항성을 갖도록 만들어졌습니다. md5보다 훨씬 더. 당신은 MD5로 곧이 UUID로서 당신은 ID 충돌의 위험이 높은이
Cruncher의

2
SET new.api_key = COALESCE(new.api_key, uuid())기존 값을 유지합니다.
라이언

33

현재 MySQL의 v8.0.13 이 필드에 대한 기본 값으로 식을 사용할 수 있습니다 :

DEFAULT 절에 지정된 기본값은 리터럴 상수 또는 식일 수 있습니다. 한 가지 예외를 제외하고 표현식 기본값을 괄호로 묶어 리터럴 상수 기본값과 구분합니다.

CREATE TABLE t1 (
  uuid_field     VARCHAR(32) DEFAULT (uuid()),
  binary_uuid    BINARY(16)  DEFAULT (UUID_TO_BIN(UUID()))
);

2
답변에 이미 연결된 문서에 따라 ... 저장된 함수 및 사용자 정의 함수는 허용되지 않습니다 . 즉, 기본 표현식으로 사용할 수있는 유일한 함수는 내장 함수입니다.
asherbar

2
2020 년 5 월 현재 이것은 정답이 될 것입니다. 트리거를 사용하는 다른 답변은 더 이상 사용되지 않습니다.
John Stock

사소한 세부 사항 : varchar(32)이어야합니다varchar(36)
Jared Beck

@JaredBeck 대시를 저장하지 않으면 32가 괜찮다고 생각합니다.
앨빈 톰슨

@JohnStock이 메서드는 사용자 정의 또는 저장된 함수의 사용을 허용하지 않으므로 더 이상 사용되지 않는 트리거 사용을 선언하는 것이 약간 시기적 일 수 있습니다.
앨빈 톰슨

21

이미 언급했듯이 할 수 없습니다.

이 동작을 시뮬레이션하려면 다음과 같이 트리거를 사용할 수 있습니다.

CREATE TRIGGER before_insert_app_users
BEFORE INSERT ON app_users
FOR EACH ROW
  IF new.uuid IS NULL
  THEN
    SET new.uuid = uuid();
  END IF;

다음과 같이 이전의 기존 행을 업데이트해야합니다.

UPDATE app_users SET uuid = (SELECT uuid());

9

안타깝게도 MySQL 5에는 기본값으로 상수가 필요합니다. 이 문제는 아래 링크에서 훨씬 더 자세히 논의되었습니다. 그러나 유일한 대답은 null을 허용하고 테이블 트리거를 추가하는 것입니다.

MySQL은 최근에야 UUID를 DB 패키지의 일부로 받아들였으며 우리가 원하는만큼 풍부한 기능이 아닙니다.

http://www.phpbuilder.com/board/showthread.php?t=10349169


1
NULL을 허용하고 트리거에 의존하면 작동 할 수 있지만 대부분의 개발자는이를 매우 해킹적인 솔루션이라고 생각합니다. 개인적으로 추천하는 것이 아니라 각자에게 추천합니다.
TravisO 2013-09-13

7

나는 당신이 할 수 없다고 믿습니다 :

기본값은 상수 여야합니다. 함수 나 표현식이 될 수 없습니다.


사실이 아닙니다, 당신은 GETDATE ()를 사용할 수 있습니다
AMR 오사마

6
@amrosama-아니요, 할 수 없습니다. getdate()MySQL 기능도 아닙니다. 대답의 링크는 유일한 예외를 설명합니다. «CURRENT_TIMESTAMP를 TIMESTAMP 열의 기본값으로 지정할 수 있습니다» .
Álvaro González

1
CURRENT_TIMESTAMP는 기본값으로 사용할 수있는 유일한 "함수"입니다. 나머지는 모두 상수 여야합니다 (불행히도).
Troy Morehouse 2015

3
기술적으로 AUTO_INCREMENT는 기본값을 동적으로 설정하는 "함수"로도 볼 수 있습니다.
Rikaelus

1

MySQL의 UUID()return CHAR(36)및 UUID를 텍스트로 저장하는 것은 분명히 비효율적입니다. 대신 열은이어야하며 데이터를 삽입 할 때 와 다시 읽을 때 BINARY(16)사용할 수 있습니다 .UUID_TO_BIN()BIN_TO_UUID()

CREATE TABLE app_users
(
    app_user_id SMALLINT(6) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    api_key     BINARY(16)
);

CREATE TRIGGER before_insert_app_users
BEFORE INSERT ON app_users
FOR EACH ROW
  IF new.api_key IS NULL
  THEN
    SET new.api_key = UUID_TO_BIN(UUID());
  END IF;

MySQL은 이것이 UUID라는 사실을 알지 못하기 때문에 바이너리로 저장된 문제를 해결하기 어려울 수 있습니다. 이 문서에서는 공간을 차지하지 않거나 별도의 바이너리 및 텍스트 버전을 동기화하는 것에 대해 걱정하지 않고 필요에 따라 UUID를 텍스트로 변환하는 생성 된 열을 만드는 방법을 설명합니다. https://mysqlserverteam.com/storing-uuid-values-in -mysql-tables /


0

위의 답변이 이전 버전인지 확실하지 않지만 unhex () 함수를 사용하여이 작업을 수행 할 수있는 곳을 보았습니다. 나는 그것을 시도하고 작동합니다. (마리아 db 버전 10.2)

넌 할 수있어

.... column_name binary(16) not null default unhex(replace(uuid(),'-',''))   

그리고 그것은 작동합니다. uuid를 보려면 hex (column_name)을 수행하십시오.


0

버전 10.2.1부터 MariaDB에서는 가능합니다. 설명서를 참조하십시오 .

CREATE TABLE test ( uuid BINARY(16) PRIMARY KEY DEFAULT unhex(replace(uuid(),'-','')) );
INSERT INTO test () VALUES ();
SELECT * FROM test;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.