RE: [GENERAL] Database Best Practices

Поиск
Список
Период
Сортировка
От Terence Chan
Тема RE: [GENERAL] Database Best Practices
Дата
Msg-id 000001bed27c$0431c1e0$9d4fb8d2@terence.cetec.com.hk
обсуждение исходный текст
Ответ на Re: [GENERAL] Database Best Practices  ("Oliver Elphick" <olly@lfix.co.uk>)
Список pgsql-general
Yes, Oliver is right.

We don't even have city here in Hong Kong. You know Hong Kong is now a city
of China, but Hong Kong also has its own Country Code.

I really hate to fill in a web form which force me to enter n/a into the Zip
Code, City etc...

R.

Terence Chan
Cetec Ltd.
Hong Kong


-----Original Message-----
From:    owner-pgsql-general@postgreSQL.org
[mailto:owner-pgsql-general@postgreSQL.org] On Behalf Of Oliver Elphick
Sent:    Tuesday, July 20, 1999 2:27 PM
To:    Gary Hoffman
Cc:    pgsql-general@postgreSQL.org
Subject:    Re: [GENERAL] Database Best Practices

Gary Hoffman wrote:
  >To all the database experts out there:
  >
  >As I begin to design my PostGreSQL tables, I'm looking for some
  >over-the-shoulder advice on the order of "best practices"
recommendations.
  >Has anyone gathered their experience together into such a book or
website?
  >
  >For example, I'd like to know, in designing a name-and-address table,
  >  - should a title field be provided? (Mr., Dr., etc.)
  >  - how about a suffix (Jr., III, etc.)
  >  - how many address lines should I have for a home address?
  >  - should all the fields be type 'text'? Should Zip be 'text' or 'int4'?
  >  - what schema handles Zip-plus-four best (including the blasted
hyphen)?
  >  - what is the best database schema for a universal, international
  >address table that includes individuals and companies?

If you want a database that can take international addresses, forget about
the rigid scheme of US addresses; most countries are much more free-form.

British postcodes are not numeric (mine is "PO30 1XP"), so a zip field that
is typed int4 would not accommodate British codes at all.

A full postal address might look like this:

  Mr A.B. Cousins                      name
  Personnel Manager                    position
  Contorted Widgets Ltd                company
  Contortion House                     building name
  5 Park Road                          street address
  Acme Industrial Estate               block
  Little Wittering                     village
  Trumpington                          post town
  Hexhamshire                          county
  TR12 5SQ                             post code
  UK                                   country

That's extreme, but I've seen some nearly as bad.  The Post Office
don't need all of that, but it helps someone who is driving around and
trying to find the place.

Putting them together is more of a problem, since the order of fields
differs between countries.  I believe German addresses go from larger
area to smaller rather than smaller to larger, for example.


Here's a sample schema that differentiates between individuals and
organisations.  It regards addresses as separate from people, because a
person can have more than one address, and people can share the same
address.

======================== schema ===================================
-- refint functions (from postgresql-contrib package).  These are
-- needed until foreign keys are implemented in PostgreSQL
\i /usr/lib/postgresql/modules/refint.sql

-------------------------- country --------------------------------
create table country
(
        id              char(2)         primary key
                                        check (id ~ '[A-Z]{2}'),
        name            text            not null,
        region          text,
        telcode         text
)
;

-- foreign key triggers
create trigger country_fref
        before DELETE or UPDATE on country
        for each row execute procedure
        check_foreign_key(1, 'restrict', 'id',
                'address', 'country'
                );

-- country contains the full list of ISO country codes, and the region of
-- the world where those countries are to be found.
-- id      = ISO country code
-- name    = country name
-- region  = continent or area where the country is
-- telcode = telephone code for the country

-------------------------- address --------------------------------
create table address
(
        id              int             primary key,
        house           text,
        number          text,
        street          text,
        village         text,
        town            text            not null,
        county          text,
        postcode        char(9),
        country         char(2)         references country (id),
        phone1_country  text,
        phone1_area     text,
        phone1_number   text,
        phone1_ext      text,
        phone2_country  text,
        phone2_area     text,
        phone2_number   text,
        phone2_ext      text,
        fax_country     text,
        fax_area        text,
        fax_number      text,
        fax_ext         text,
        comment         text
)
;

-- Use SPI triggers until foreign keys are implemented
create trigger address_pkref
create trigger address_pkref
        before INSERT or UPDATE on address
        for each row execute procedure
        check_primary_key('country', 'country', 'id');

create trigger address_fref1
        before DELETE or UPDATE on address
        for each row execute procedure
        check_foreign_key(1, 'restrict', 'id',
                'person_address', 'address');

create trigger address_fref2
        before DELETE or UPDATE on address
        for each row execute procedure
        check_foreign_key(3, 'setnull', 'id',
                'individual', 'address',
                'organisation', 'address',
                'person', 'address'
                );

-- id       = unique identifier of this address
-- house    = house name
-- number   = house number
-- street   = street address (excluding house name or number)
-- village  = second part of street address, if any
-- town     = city or post town
-- county   = county (may sometimes be blank)
-- postcode = post or zip code
-- country  = country code
-- phone1_country   = primary telephone country code
-- phone1_area      = primary telephone area code
-- phone1_number    = primary telephone number
-- phone1_ext       = primary telephone extension
-- phone2_country   = secondary telephone country code
-- phone2_area      = secondary telephone area code
-- phone2_number    = secondary telephone number
-- phone2_ext       = secondary telephone extension
-- fax_country   = fax telephone country code
-- fax_area      = fax telephone area code
-- fax_number    = fax telephone number
-- fax_ext       = fax telephone extension
-- comment       = free text

-- A person (of any kind) can have one or more addresses.  All fields here
-- are associated with a particular physical location


-------------------------- person --------------------------------
create table person
(
        id              char(10)        primary key,
        name            text            not null,
        address         int             references address (id),
        salutation      text            default 'Dear Sir',
        envelope        text,
        email           text,
        www             text,
        comment         text
)
;

-- Use SPI triggers until foreign keys are implemented


create trigger person_pkref
        before INSERT or UPDATE on person
        for each row execute procedure
        check_primary_key('address', 'address', 'id');

create trigger person_fref_x
        before DELETE or UPDATE on person
        for each row execute procedure
        check_foreign_key(1, 'restrict', 'id',
                'person_address', 'person'
                );


-- Top-level class that describes persons (living or otherwise)
-- id         = identifier
-- address    = id of the primary address of this person
-- salutation = how to address this person in the start of a letter
--                  (e.g.: "Dear Fred")
-- envelope   = how to address this person on an envelope
--                  (e.g.: "Mr F.G. Bloggs")
-- email      = email address
-- www        = Web URL
-- comment       = free text

-- Dependencies: address


-------------------------- individual --------------------------------
create function name(bpchar, bpchar, bpchar) returns bpchar
        as '/usr1/proj/bray/sql/funcs.so' language 'c';

create table individual
(
        gender          char(1)         check (gender = 'M' or gender = 'F'
or gender is null),
        born            date        check ((born >= '1 Jan 1880' and born <=
'today') or born is null),
        surname         text,
        forenames       text,
        title           text,
        old_surname     text,
        mobile          text,
        ni_no           text

        constraint is_named check (not (surname isnull and forenames
isnull))
)
        inherits (person)
;

create trigger individual_pkref
        before INSERT or UPDATE on individual
        for each row execute procedure
        check_primary_key('address', 'address', 'id');

create trigger individual_fref_x
        before DELETE or UPDATE on individual
        for each row execute procedure
        check_foreign_key(1, 'restrict', 'id',
                'person_address', 'person',
                'organisation', 'contact'
                );

-- Table of living individuals (as opposed to firms or legal persons)
-- gender    = 'M' or 'F'
-- born      = date of birth
-- surname   = surname
-- forenames = forenames
-- title     = Mr, Mrs, etc
-- old_surname   = maiden name, etc.

-- Inheritance: person



-------------------------- organisation --------------------------------
create table organisation
(
        structure      char(1)         check (structure='L' or structure='C'
or structure='U' or structure='O'),
    contact        char(10)        references individual (id),
    old_name       text
)
        inherits (person)
;


create trigger organisation_pkref
        before INSERT or UPDATE on organisation
        for each row execute procedure
        check_primary_key('address', 'address', 'id');

create trigger organisation_pkref_c
        before INSERT or UPDATE on organisation
        for each row execute procedure
        check_primary_key('contact', 'individual', 'id');

create trigger organisation_fref_x
        before DELETE or UPDATE on organisation
        for each row execute procedure
        check_foreign_key(1, 'restrict', 'id',
                'person_address', 'person'
                );



-- Defines persons that are not individuals
-- contact      = id of the primary person to be contacted when dealing
--                with this organisation
-- structure    = L(imited), C(orporation), U(nincorporated) or O(ther)
-- old_name     = previous organisation name (if any)

-- Inheritance: person
-- Dependencies: individual, address

---------------- person_address relation ----------------------
create table person_address
(
        person          char(10)        not null
                                         -- references person*,
                                         references person(id),
        address         int             not null
                                         references address(id),
        function        text            not null,

        primary key (person, address, function)
)
;

-- refint triggers
create trigger person_address_pkref_1
        before INSERT or UPDATE on person_address
        for each row execute procedure
        check_primary_key('person', 'person*', 'id');

create trigger person_address_pkref_2
        before INSERT or UPDATE on person_address
        for each row execute procedure
        check_primary_key('address', 'address', 'id');

-- Relation of people to addresses (many-to-many relationship)
-- person   =  id of a person
-- address  =  id of an address
-- function =  use of address (e.g. accounts, deliveries...)

======================== schema ===================================
--
      Vote against SPAM: http://www.politik-digital.de/spam/
                 ========================================
Oliver Elphick                                Oliver.Elphick@lfix.co.uk
Isle of Wight                              http://www.lfix.co.uk/oliver
               PGP key from public servers; key ID 32B8FAA1
                 ========================================
     "Behold, what manner of love the Father hath bestowed
      upon us, that we should be called the sons of God..."
                                I John 3:1







В списке pgsql-general по дате отправления:

Предыдущее
От: "Oliver Elphick"
Дата:
Сообщение: Re: [GENERAL] Database Best Practices
Следующее
От: Frank Bringezu
Дата:
Сообщение: unsubscribe