열의 기본값을 다른 두 열의 연결 값으로 설정 하시겠습니까?


13

Postgresql 8.1 데이터베이스가 있습니다. 하나 개의 테이블에서 세 개의 열이 있습니다 : first_name, last_name, display_name.

기본값을로 설정할 display_namefirst_name + " " + last_name있습니까?


나는 이것이 7 세 이상의 게시물이라는 것을 알고 있습니다. 그러나 호기심을 나타 내기 위해이 경우에보기를 사용해서는 안됩니까? 업데이트가 필요하지 않고, 상점 오버 헤드가없고, 트리거가 필요하지 않습니까?
가혹한

답변:


15

트리거를 사용하십시오.

다음은 기본으로 사용할 수있는 코드입니다. UPDATE도 처리해야하는 경우 약간만 변경하면됩니다.

 create table people
 (
   first_name varchar(20),
   last_name varchar(20),
   display_name varchar(40)
 );
CREATE TABLE
 CREATE OR REPLACE FUNCTION people_insert() RETURNS trigger AS '
     BEGIN
         NEW.display_name := NEW.first_name||'' ''||NEW.last_name;
         RETURN NEW;
     END;
 ' LANGUAGE plpgsql;

 postgres=# CREATE FUNCTION


 CREATE TRIGGER people_insert BEFORE INSERT OR UPDATE ON people FOR 
 EACH ROW EXECUTE PROCEDURE people_insert();

postgres=# CREATE TRIGGER
 insert into people values ('Larry','Ellison');

postgres=# INSERT 0 1

 postgres=# select * from people;
 first_name | last_name | display_name
------------+-----------+---------------
 Larry      | Ellison   | Larry Ellison
(1 row)

postgres=#

감사! 라인 CREATE TRIGGER people_insert BEFORE INSERT OR UPDATE...이 업데이트도 처리 하지 않습니까?
MattSayar

오 예. 반쯤
자야 했어요

관심이 있다면 display_name은 41이되어야합니다. 두 개의 20 자 열 사이에 공백을 추가하므로.
isaaclw

나는이 솔루션은 :-( 삽입 작업에 대한 오버 헤드가 약 15 %를 추가 것을 볼
Akvel

17

실제로 값을 저장할 필요는 없습니다 . 생성 된 열과 매우 유사하게 참조 할 수있는 함수를 작성할 수 있습니다. 한 가지주의 할 점은 참조는 항상 테이블 또는 별명 이름으로 규정되어야한다는 것입니다.

CREATE TABLE person
  (
    id int PRIMARY KEY,
    first_name text,
    last_name text NOT NULL
  );

INSERT INTO person
  VALUES
    (1, 'John', 'Smith'),
    (2, 'Jane', 'Doe'),
    (3, NULL, 'Prince');

CREATE FUNCTION display_name(rec person)
  RETURNS text
  STABLE
  LANGUAGE SQL
  COST 5
AS $$
  SELECT
    CASE
      WHEN $1.first_name IS NULL THEN ''
      ELSE $1.first_name || ' '
    END || $1.last_name;
$$;

SELECT p.id, p.display_name FROM person p;

결과 :

아이디 | 이름 표시하기
---- + --------------
  1 | 존 스미스
  2 | 제인도
  3 | 왕자
(3 행)

트라이 그램 유사성에 기반한 KNN 검색 사용을 포함하여 생성 된 값을 인덱스 할 수도 있습니다. 예를 들면 다음과 같습니다.

CREATE EXTENSION pg_trgm;

CREATE INDEX person_trgm_name
  ON person
  USING gist
  (display_name(person) gist_trgm_ops);

SELECT
    p.id,
    p.display_name,
    similarity(p.display_name, 'Jane')
  FROM person p
  ORDER BY p.display_name <-> 'Jane'
  LIMIT 2;

이 유형의 검색은 검색 문자열에서 "거리"순서로 인덱스 스캔에서 행을 반환합니다. 이들이 얼마나 "가까운"지 보려면 거리 연산자 ( <->) 또는 similarity()함수 (1 거리)를 사용할 수 있습니다. KNN 검색은 매우 큰 데이터 세트가 있더라도 K "가장 가까운 이웃"을 매우 빠르게 반환 할 수 있습니다.


실제로 이전 버전과의 호환성을 위해 값을 저장해야하지만 이것은 매우 멋진 접근법입니다! 저의 OCD 부분은 또한 NULL 성을 확인하기를 원하지만 그 시점에서 걱정해야 할 더 큰 데이터 무결성 문제가 있음을 의미 할 것입니다.
MattSayar

글쎄, 나는 내 모범 last_name에 있다고 선언했다 NOT NULL. :-) 우리는 테이블에 있고 트리거에 의해 유지되는 것과 같은 이름 열을 가지고 있었고 많은 어려움 없이이 접근법으로 전환했지만 프레임 워크는 항상 별칭을 사용하고 항상 참조를 한정하므로 부분이 쉽습니다. 열 참조를 규정하는 데 일관성이없는 코드가 있다면 모든 경우를 추적하기가 어려울 수있는 곳을 알 수 있습니다.
kgrittn

2

열 테이블에서 DEFAULT 설정으로 nope.

가장 좋은 방법은 계산하려는 각 열에 대해 NEW 값을 가진 TRIGGER입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.