Mam bazę danych Postgresql 8.1. W jednej tabeli, istnieją trzy kolumny: first_name
, last_name
, display_name
.
Czy można ustawić wartość domyślną display_name
to first_name + " " + last_name
?
Mam bazę danych Postgresql 8.1. W jednej tabeli, istnieją trzy kolumny: first_name
, last_name
, display_name
.
Czy można ustawić wartość domyślną display_name
to first_name + " " + last_name
?
Odpowiedzi:
Użyj spustu.
Oto kod, którego możesz użyć jako podstawy. Jeśli musisz także obsługiwać AKTUALIZACJE, wymagana jest tylko niewielka zmiana.
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...
poradziłaby również z aktualizacją?
Nie musisz tak naprawdę przechowywać wartości; możesz utworzyć funkcję, do której można będzie się odwoływać podobnie do wygenerowanej kolumny. Jedynym zastrzeżeniem jest to, że odwołania muszą zawsze być kwalifikowane nazwą tabeli lub aliasu.
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;
Wyniki:
id | wyświetlana nazwa ---- + -------------- 1 | John Smith 2 | Jane Doe 3 | Książę (3 rzędy)
Możesz nawet indeksować wygenerowaną wartość, w tym za pomocą wyszukiwań KNN opartych na podobieństwie trygramu. Na przykład:
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;
Ten typ wyszukiwania zwraca wiersze ze skanu indeksu w kolejności „odległości” od ciągu wyszukiwania. Jeśli chcesz zobaczyć, jak były „blisko”, możesz użyć operatora odległości ( <->
) lub similarity()
funkcji (która wynosi 1 - odległość). Wyszukiwanie KNN może bardzo szybko zwrócić K „najbliższych sąsiadów”, nawet przy bardzo dużym zestawie danych.
last_name
się NOT NULL
w moim przykładzie. :-) Mieliśmy takie kolumny nazw, które były w tabeli i były obsługiwane przez wyzwalacze i przeszły na to podejście bez większego bólu, ale nasz framework zawsze używa aliasu i zawsze kwalifikuje referencje, więc ta część była łatwa. Jeśli masz kod, który nie jest spójny w odniesieniu do kwalifikujących się odniesień do kolumn, widzę, gdzie może być problem ze śledzeniem wszystkich tych przypadków.