• Aucun résultat trouvé

Not Backed Up by Default

Dans le document IntroductionandConcepts PostgreSQL (Page 109-115)

Figure 7.2: Columns withOIDs

7.2 Object Identification Number Limitations

This section covers three limitations of object identification numbers.

Nonsequential Numbering

The global nature of object identification assignment means mostOIDs in a table are not sequential.

For example, if you insert one customer today, and another one tomorrow, the two customers will not get sequentialOIDs. In fact, theirOIDs could differ by thousands because anyINSERTs into other tables between the two customer inserts would increment the object counter. If theOIDis not visible to users, this gap in numbering is not a problem. The nonsequential numbering does not affect query processing. However, if users can see and enter these numbers, it might seem strange that customer identification numbers are not sequential and have large gaps between them.

Nonmodifiable

AnOIDis assigned to every row duringINSERT. UPDATEcannot modify the system-generatedOID

of a row.

Not Backed Up by Default

During database backups, the system-generatedOIDof each row is normally not backed up. A flag must be added to enable the backup ofOIDs. See Section20.5for details.

7.3 Sequences

POSTGRESQLoffers another way of uniquely numbering rows—sequences. Sequences are named counters created by users. After its creation, a sequence can be assigned to a table as a column

DEFAULT. Using sequences, unique numbers can be automatically assigned duringINSERT.

82 CHAPTER 7. NUMBERING ROWS

Function Action

nextval(’name’) Returns the next available sequence number, and updates the counter currval(’name’) Returns the sequence number from the previous nextval() call

setval(’name’, newval) Sets the sequence number counter to the specified value Table 7.1: Sequence number access functions

The advantage of sequences is that they avoid gaps in numeric assignment, as happens with

OIDs.5 Sequences are ideal for use as user-visible identification numbers. If one customer is created today, and another is created tomorrow, then the two customers will have sequential numbers because no other table shares the sequence counter.6

Sequence numbers are generally unique only within a single table. For example, if a table has a unique row numbered 937, another table might have a row numbered 937 as well, assigned by a different sequence counter.

7.4 Creating Sequences

Sequences are not created automatically, likeOIDs. Instead, you must use theCREATE SEQUENCE

command. Three functions control the sequence counter, as shown in Table7.1.

Figure 7.3shows an example of sequence creation and sequence function usage. The first command creates the sequence, then various sequence functions are called. Note that theSELECTs do not include aFROMclause. Sequence function calls are not directly tied to any table. In the figure:

• nextval() returns ever-increasing values.

• currval() returns the previous sequence value without incrementing.

• setval() sets the sequence counter to a new value.

Currval() returns the sequence number assigned by a prior nextval() call in the current session.

It is not affected by the nextval() calls of other users, which allows reliable retrieval of nextval() assigned values in later queries.

7.5 Using Sequences to Number Rows

Configuring a sequence to uniquely number rows involves several steps:

5This is not completely accurate. Gaps can occur if a query is assigned a sequence number as part of an aborted transaction.

See Section10.2for a description of aborted transactions.

6Tables can be configured to share sequence counters, if desired.

7.5. USING SEQUENCES TO NUMBER ROWS 83

test=> CREATE SEQUENCE functest_seq;

CREATE

test=> SELECT nextval(’functest_seq’);

nextval

---1 (1 row)

test=> SELECT nextval(’functest_seq’);

nextval

---2 (1 row)

test=> SELECT currval(’functest_seq’);

currval

---2 (1 row)

test=> SELECT setval(’functest_seq’, 100);

setval

---100 (1 row)

test=> SELECT nextval(’functest_seq’);

nextval

---101 (1 row)

Figure 7.3: Examples of sequence function use

84 CHAPTER 7. NUMBERING ROWS

test=> INSERT INTO customer VALUES (nextval(’customer_seq’), ’Bread Makers’);

INSERT 19004 1

test=> INSERT INTO customer (name) VALUES (’Wax Carvers’);

INSERT 19005 1

test=> INSERT INTO customer (name) VALUES (’Pipe Fitters’);

INSERT 19008 1

Figure 7.4: Numbering customer rows using a sequence

1. Create the sequence.

2. Create the table, defining nextval() as the column default.

3. During theINSERT, do not supply a value for the sequenced column, or use nextval().

Figure 7.4 shows the use of a sequence for unique row numbering in the customer table. The first statement creates a sequence counter named customer_seq. The second command creates the customer table, and defines nextval(’customer_seq’) as the default for the customer_id column.

The first INSERTmanually supplies the sequence value for the column. The nextval(’customer_-seq’) function call will return the next available sequence number, and increment the sequence counter. The second and third INSERTs allow the nextval(’customer_seq’)DEFAULTto be used for the customer_id column. Remember, a column’sDEFAULTvalue is used only when a value is not supplied by anINSERT statement. (This is covered in Section4.4.) TheSELECTshows that the customer rows have been sequentially numbered.

7.6. SERIAL COLUMN TYPE 85

test=> CREATE TABLE customer ( test(> customer_id SERIAL, test(> name CHAR(30) test(> );

NOTICE: CREATE TABLE will create implicit sequence ’customer_customer_id_-seq’ for SERIAL column ’customer.customer_id’

NOTICE: CREATE TABLE/UNIQUE will create implicit index ’customer_customer_id_-key’ for table ’customer’ ---+---+---customer_id | int4 | not null default nextval(’customer_customer_id_seq’::text) name | char(30) |

Index: customer_customer_id_key

test=> INSERT INTO customer (name) VALUES (’Car Wash’);

INSERT 19152 1

Figure 7.5: The customer table usingSERIAL

7.6 Serial Column Type

An even easier way to use sequences exists. If you define a column of typeSERIAL,a sequence will be automatically created, and a properDEFAULTwill be assigned to the column. Figure 7.5 shows an example. The firstNOTICE line indicates that a sequence was created for theSERIAL

column. Do not be concerned about the secondNOTICEline in the figure. (Indexes are covered in Section11.1.)

7.7 Manually Numbering Rows

Some people wonder whyOIDs and sequences are needed at all. Why can’t a database user just find the highest number in use, add one, and use the result as the new unique row number? In reality,OIDs and sequences are preferred for several reasons:

86 CHAPTER 7. NUMBERING ROWS

• Performance

• Concurrency

• Standardization

First, it is usually a slow process to scan all numbers currently in use to find the next available number. Referring to a counter in a separate location is faster. Second, if one user gets the highest number, and another user is looking for the highest number at the same time, the two users might choose the same next-available highest number. Of course, in this case, the number would not be unique. Such concurrency problems do not occur when usingOIDs or sequences. Third, it is more reliable to use database-supplied unique number generation than to generate unique numbers manually.

7.8 Summary

BothOIDs and sequences allow the automatic unique numbering of rows.OIDs are always created and numbered, while sequences require more work to configure. Both are valuable tools for uniquely numbering rows.

Chapter 8

Dans le document IntroductionandConcepts PostgreSQL (Page 109-115)