2012-04-07 12 views
1

Ich habe eine Tabelle, die providerid|provider_name|url
hat Ich habe eine andere Tabelle user die id|name|provider_idgespeicherte Prozedur Namen id Übersetzung

I hat eine Funktion create_user(name,provider_name) erstellen möchten, die jeder Anbieter gibt es mit diesem Anbieter überprüft, ob Name. Falls vorhanden, die Zeile einfügen und die letzte Zeilen-ID zurückgeben. andere weise zurück 0. Ich habe die Integrität des Fremdschlüssels unter provider_id ->user.id eingerichtet. und beide id Felder sind pkey und serial

insert into users 
    (name, provider_id) 
values($1, (
    select id from provider where name = $2 
)) returning id 

Ist das in Ordnung?

Antwort

1

Ihre Aussage

INSERT INTO users (name, provider_id) 
VALUES ($1, (SELECT id FROM provider WHERE name = $2)) 
RETURNING id; 

wird funktionieren, wenn Sie users.provider_id NOT NULL machen. Ohne diesen Wert würden Sie einen Wert für eine nicht vorhandene provider_id eingeben. Eine Fremdschlüsseleinschränkung verbietet dies nicht!
(ich nehme an, Sie gemeint: provider_id -> provider.id, nicht -> user.id.)

Sie können oder nicht users.name UNIQUE machen möchten können doppelte Namen zu verbieten.

Mit eindeutigen Namen wäre ein Ersatzprimärschlüssel (user.id) in den meisten Fällen sinnvoll. Die Behandlung einer Ganzzahl ist schneller als die Behandlung eines (längeren) Textes. Vor allem, wenn Sie mehrere andere Tabellen haben, die auf den Primärschlüssel der Tabelle verweisen, was normalerweise der Fall ist. Die Verwendung einer Ganzzahl für die Fremdschlüssel und die zugehörigen Indizes ist erheblich schneller und benötigt weniger Speicherplatz auf der Festplatte und im Arbeitsspeicher. Es ist auch einfacher, später Änderungen vorzunehmen, wie z. B. das Teilen der name in firstname und surname.

0

Das funktioniert nicht, wenn mehrere Benutzerzeilen mit diesem Namen vorhanden sind. Wenn doppelte Namen unter den Benutzern nicht möglich sind, dann wäre es in Ordnung. (Wenn das wirklich ein Name ist, scheint es nicht klug anzunehmen, dass keine Duplikate möglich sind.)

Natürlich, wenn doppelte Benutzernamen nicht möglich sind, gibt es keinen guten Grund, eine ID-Spalte in der Benutzertabelle zu haben ; Ich würde dringend empfehlen, nur den Primärschlüssel zu nennen und die ID-Spalte zu verlassen. (Es sollte möglicherweise auch etwas anderes genannt werden.) Das würde diese Abfrage zusammen mit ganzen Klassen von Abfragen vereinfachen und beschleunigen. Bei diesem Schemadesign wird auch davon ausgegangen, dass ein Benutzer höchstens einen Anbieter (wenn provider_id NULL-fähig ist) oder genau einen Anbieter (wenn provider_id NOT NULL ist) haben kann.