답변:
DOMAIN
의나는 citext
대소 문자를 구분하지 않는 것만으로는 충분 하지 않다고 생각한다 [1] . PostgreSQL을 사용 하여 유형에 대해 정의 된 제약 조건 인 사용자 지정 도메인 을 만들 수 있습니다 . 예를 들어 유형 이상의 도메인을 만들 수 있습니다 .citext
text
type=email
사양 사용현재 이메일 주소에 관한 질문에 대한 가장 정확한 답변은 RFC5322에 명시되어 있습니다 . 그 스펙은 엄청나게 복잡하다 [2] . 그래서 모든 것이 그것을 깨뜨린 다. HTML5에는 email 에 대한 다른 사양이 있습니다 .
이 요구 사항은 RFC 5322를 고의적으로 위반하는 것으로, 동시에 너무 엄격하고 ( "@"문자 앞), 모호한 ( "@"문자 뒤), 너무 느슨한 (주석 허용) 전자 메일 주소의 구문을 정의합니다. , 공백 문자 및 대부분의 사용자에게 친숙하지 않은 방식으로 따옴표로 묶은 문자열)을 여기에서 실제로 사용할 수 있습니다. [...] 다음 JavaScript 및 Perl 호환 정규식은 위 정의의 구현입니다.
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
이것은 아마도 당신이 원하는 것 일 것이고, HTML5에 충분하다면 아마 당신에게 충분할 것입니다. PostgreSQL에서 직접 사용할 수 있습니다. 또한 citext
여기에서 사용 합니다 (기술적으로 대문자 또는 소문자를 제거하여 정규식을 약간 시각적으로 간단히 나타낼 수 있음을 의미합니다).
CREATE EXTENSION citext;
CREATE DOMAIN email AS citext
CHECK ( value ~ '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$' );
이제 할 수있는 ...
SELECT 'asdf@foobar.com'::email;
하지만
SELECT 'asdf@foob,,ar.com'::email;
SELECT 'asd@f@foobar.com'::email;
둘 다 돌아 오기 때문에
ERROR: value for domain email violates check constraint "email_check"
이것도 citext를 기반으로하기 때문에
SELECT 'asdf@foobar.com'::email = 'ASdf@fooBAR.com';
기본적으로 true를 반환합니다.
plperlu
/ 사용Email::Valid
중요한 참고 사항으로을 사용하는 것이 훨씬 복잡한 올바른 방법이 plperlu
있습니다. 이 수준의 정확성이 필요한 경우 원하지 않습니다citext
. Email::Valid
도메인에 MX 레코드가 있는지 확인할 수도 있습니다 (이메일 문서 :: Valid 문서). 먼저 plperlu를 추가하십시오 (수퍼 유저 필요).
CREATE EXTENSION plperlu;
그런 다음 함수를 만들고로 표시합니다 IMMUTABLE
.
CREATE FUNCTION valid_email(text)
RETURNS boolean
LANGUAGE plperlu
IMMUTABLE LEAKPROOF STRICT AS
$$
use Email::Valid;
my $email = shift;
Email::Valid->address($email) or die "Invalid email address: $email\n";
return 'true';
$$;
그런 다음 도메인을 생성 ,
CREATE DOMAIN validemail AS text NOT NULL
CONSTRAINT validemail_check CHECK (valid_email(VALUE));
citext
이 기술적으로 잘못되었습니다. SMTP는 local-part
대소 문자를 구분하는 것으로 정의 합니다. 그러나 다시 말하지만, 이것은 사양 이 어리석은 경우입니다 . 그것은 자신의 정체성 위기를 포함합니다. 사양은 local-part
(이전의 부분 @
) "대소 문자를 구분해야합니다"... "대소 문자를 구분해야합니다" 라고 말하지만 "사서함 로컬 부분의 대소 문자 구분을 악용하면 상호 운용성을 방해하고 권장하지 않습니다."이 정규식 중 어느 것도 전체 전자 메일 주소 나 로컬 부분 또는 도메인 이름에 길이 제한을 적용하지 않습니다. RFC 5322는 길이 제한을 지정하지 않습니다. 이는 실제로 이메일을 보내는 SMTP 프로토콜과 같은 다른 프로토콜의 제한에서 비롯됩니다. RFC 1035는 도메인이 63 자 이하 여야한다고 명시하지만 구문 사양에는 도메인을 포함하지 않습니다. 진정한 정규 언어는 길이 제한을 적용 할 수없고 연속적인 하이픈을 동시에 허용하지 않기 때문입니다.
a-z
와 A-Z
캐릭터 클래스를 모두 가질 이유가 있습니까?
~
는 대소 문자를 구분 하므로 (a) ~*
대소 문자를 구분하지 않거나 (b) char 클래스에 대문자와 소문자를 사용해야 합니다.
citext
는 ~
대소 문자를 구분하지 않는 것 같습니다. 이것이 내가 묻는 이유입니다.
CITEXT
이메일 주소 는 (실제로) 대소 문자를 구분하지 않으므로 항상 이메일에 사용 합니다. 즉 John@Example.com은 john@example.com과 같습니다.
텍스트와 비교하여 중복을 방지하기 위해 고유 색인을 설정하는 것이 더 쉽습니다.
-- citext
CREATE TABLE address (
id serial primary key,
email citext UNIQUE,
other_stuff json
);
-- text
CREATE TABLE address (
id serial primary key,
email text,
other_stuff json
);
CREATE UNIQUE INDEX ON address ((lower(email)));
이메일을 비교하는 것이 더 쉽고 오류가 덜 발생합니다.
SELECT * FROM address WHERE email = 'JOHN@example.com';
비교하자면:
SELECT * FROM address WHERE lower(email) = lower('JOHN@example.com');
CITEXT
"citext"라는 표준 확장 모듈에 정의 된 유형 이며 다음을 입력하여 사용할 수 있습니다.
CREATE EXTENSION citext;
PS text
와는 varchar
사실상 포스트 그레스에서 동일 및 사용에 대한 수수료가없는 text
한 예상을했던 것으로서은. 이 답변을 확인하십시오 : text와 varchar의 차이점
varchar(254)
이메일 주소는 항상 254 자 이하 여야합니다.
https://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address를 참조 하십시오
PostgreSQL에는 전자 메일 주소에 대한 기본 제공 유형이 없지만 일부 기여 데이터 유형이 있습니다.
또한 고유 키를 추가하려는 경우 이메일 주소를 표준화하기 위해 트리거 또는 이러한 논리를 추가 할 수 있습니다.
특히 domain
이메일 주소 의 일부 ( local-part
@ 형식 domain
은 대소 문자를 구분하지 않지만 대소 문자를 구분 local-part
해야합니다. http://tools.ietf.org/html/rfc5321#section-2.4를 참조하십시오.
다른 고려 사항은 이름과 이메일 주소를 양식에 저장하려는 "Joe Bloggs" <joe.bloggs@hotmail.com>
경우 254 자보다 긴 문자열이 필요하고 고유 제한 조건을 의미있게 사용할 수 없습니다. 나는 이것을하지 않을 것이며 이름과 이메일 주소를 별도로 저장하는 것이 좋습니다. 이 형식의 주소는 프리젠 테이션 레이어에서 항상 인쇄 할 수 있습니다.
@
) = 320입니다. 아마도 그것을 잘못 해석하고있을 것입니다.
당신은 체크 사용에 관심이있을 수있는 제약 조건을 가능한 쉽게 (하지만, 더 당신이 원하는 것보다 거부 할 수도 있고, 당신이 기능이 논의 사용 여기 와 여기 . Bascially, 그것은 특이성 사이의 트레이드 오프에 대해 전부 및 구현의 용이성. 재미있는 주제 PostgreSQL에는 기본 IP 주소 유형도 있지만 pgfoundry에는 전자 메일 데이터 유형에 대한 프로젝트가 있지만 여기에서 내가 찾은 가장 좋은 것은 전자 메일 도메인입니다.. 도메인을 변경하는 경우 도메인 정의에서 한 번만 수행하면되고 모든 검사 제한 조건을 변경하는 상위-하위 테이블을 추적하지 않아도되므로 도메인은 점검 제한 조건보다 낫습니다. 도메인은 데이터 유형과 비슷하지만 구현하기가 더 쉽습니다. Firebird에서 사용했습니다-Oracle에는 없습니다.