Thread: Question about serial vs. int datatypes

Question about serial vs. int datatypes

From
Lynna Landstreet
Date:
Not sure if the lists are currently working - I just joined both this one
and pgsql-novice, and posted a message to that one earlier in the day, but I
haven't received either any replies or even my own message back, so I don't
know if it's working. I know there was some kind of hardware failure with
regard to the lists, but I don't know how severe.

Anyway: I'm converting a FileMaker Pro database into PostgreSQL, and have a
question (actually, tons of questions, but I'll stick to one for now). Each
of the three major database files in FMP (equivalent to tables in
PostgreSQL) has a number field as a primary key which is incremented
serially as new records are added. Nice and simple, and the same thing a lot
of PostgreSQL databases use.

But... when converting an existing database that already has several hundred
records in it, I can't make that field serial in PostgreSQL, can I? Because
I don't want the existing records renumbered - that would break the links
between the different tables. But if I make the id number just a smallint
field, then I'm stuck incrementing it manually after the conversion. Is
there any way around this? Any way to import the existing records with their
id number intact, and then have it switch to serial after that for new
records?

Any advice would be appreciated...


Lynna
--
Resource Centre Database Coordinator
Gallery 44
www.gallery44.org


Re: Question about serial vs. int datatypes

From
Paul Thomas
Date:
On 05/06/2003 21:05 Lynna Landstreet wrote:

> Anyway: I'm converting a FileMaker Pro database into PostgreSQL, and have
> a
> question (actually, tons of questions, but I'll stick to one for now).
> Each
> of the three major database files in FMP (equivalent to tables in
> PostgreSQL) has a number field as a primary key which is incremented
> serially as new records are added. Nice and simple, and the same thing a
> lot
> of PostgreSQL databases use.
>
> But... when converting an existing database that already has several
> hundred
> records in it, I can't make that field serial in PostgreSQL, can I?
> Because
> I don't want the existing records renumbered - that would break the links
> between the different tables. But if I make the id number just a smallint
> field, then I'm stuck incrementing it manually after the conversion. Is
> there any way around this? Any way to import the existing records with
> their
> id number intact, and then have it switch to serial after that for new
> records?
>
> Any advice would be appreciated...


Looking at the docs and after a bit of playing around with 7.3.3, I think
this may work:

1) I believe PG _will_ accept the serial numbers you insert so importing
the data with your serial number fields should work.

2) For each serial type you will find that PG has a created a Sequence
object with a name of the form tablename_columnname_seq. After the import,
you will need to set this to the max value of your serial column with
SELECT pg_catalog.setval("sequencename", value, true);
HTH

--
Paul Thomas
+------------------------------+---------------------------------------------+
| Thomas Micro Systems Limited | Software Solutions for the Smaller
Business |
| Computer Consultants         |
http://www.thomas-micro-systems-ltd.co.uk   |
+------------------------------+---------------------------------------------+

Re: Question about serial vs. int datatypes

From
Jean-Christian Imbeault
Date:
Lynna Landstreet wrote:
 >
 > the current structure where the keywords in any given set (i.e. subject,
 > medium, etc.) are all lumped together into one long string for each
record
 > would be considered bad database design

Again, I'm no expert either but I would definitely say that is bad
design. Strangely enough my current job is also converting a FMP DB to
postgres and I had the same issue. Many data clumped into one field.

 > But if I make each keyword into a boolean field, I'm not sure how
 > to display them.

That's not a DB issue. In your case that's a web browser issue and
related to whatever web programming language you will use.

 > Pg usually return the data in the columns, not
 > the column names.

The data returned is associated with a column name so you always know
where your data came from ;)

 > When people ultimately view the database records on the
 > web, I want them to be able to see something like:
 >
 > Medium: black and white photograph
 > Subject: landscape, nature
 > Processes: hand-tinting, photocollage
 >
 > Or something to that effect, but NOT:
 >
 > black and white photograph: yes
 > landscape: yes
 > nature: yes
 > hand-tinting: yes
 > photocollage: yes

The only difference between the two versions you show here is that in
the second one you don't show the column names, but of course you (the
programmer) know what they are since you did the SELECT that fetched the
data ...

 > So I'm thinking that probably each set of keywords (medium, subject,
etc.)
 > probably needs to be a table {...]

Hum, database design. A thorny issue for the newbie. The way you decide
to go will affect many things so plan carefully.

I don't know enough about your data or database design to suggest
anything but from what I can gather of your data you would have an
exhibition/art piece (?) table in it.

Then you would have a table for, say b/w photography and in that table
you would have one entry for each art piece that fell into that
category. And so on for all the other kinds of possible ways to
categorize the art piece.

So the art piece table would no contain any information at all on what
kind of art it is. To find that out you would need to search all the
possible category tables to see if there was a matching entry for that
art piece.

I think someone may suggest that a view would make you life easier if
you did decide to go that route ...

 > but I'm not sure if there's a way to modify a select statement so that it
 > outputs the names of all columns with a yes/true/1 in them, rather than
 > outputting the values themselves.

If you go with my design you don't knew to output anything. If there is
an entry for that art piece in a particular category table then it's of
that category.

 > BTW, I'll be using PHP to create the front end
 > of this for the web site, if that makes a difference.

I'm using PHP too. So far so good ... I did have to dump out all the FMP
data into one big text file and create a custom PHP script to parse the
data and insert it into PG tables and make the necessary relationships
though.

In my case I did have the same serial issue you mentioned in your last
question but since the primary keys in FMP weren't used for anything
else but keys into tables I didn't need to actually keep the same key
id. I just found all the data in the text file that matched on that key,
parsed it, inserted it into PG, let PG assign a new serial and used the
assigned serial to create the relationships in all the other tables.

HTH,

--

Jean-Christian Imbeault


Re: Question about serial vs. int datatypes

From
Joe Conway
Date:
Lynna Landstreet wrote:
> But... when converting an existing database that already has several hundred
> records in it, I can't make that field serial in PostgreSQL, can I? Because
> I don't want the existing records renumbered - that would break the links
> between the different tables. But if I make the id number just a smallint
> field, then I'm stuck incrementing it manually after the conversion. Is
> there any way around this? Any way to import the existing records with their
> id number intact, and then have it switch to serial after that for new
> records?

You can create the field as serial. A serial data type makes the column
*default* to the next value of a sequence, but if you provide a value
(as you would during the import), the default is not used. But you will
need to set the sequence after the import so that it starts with a
number higher than any you imported. See:

http://www.us.postgresql.org/postgresql-7.3.3/functions-sequence.html

For example:

regression=# create table s1(id serial primary key, f2 text);
NOTICE:  CREATE TABLE will create implicit sequence 's1_id_seq' for
SERIAL column 's1.id'
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index 's1_pkey'
for table 's1'
CREATE TABLE
regression=# \d s1
                            Table "public.s1"
  Column |  Type   |                     Modifiers
--------+---------+----------------------------------------------------
  id     | integer | not null default nextval('public.s1_id_seq'::text)
  f2     | text    |
Indexes:
     "s1_pkey" PRIMARY KEY btree (id)

INSERT INTO s1(id,f2) VALUES (1,'hello');
INSERT INTO s1(id,f2) VALUES (2,'world');
SELECT setval('s1_id_seq',42);
INSERT INTO s1(f2) VALUES ('abc');
regression=# SELECT * FROM s1;
  id |  f2
----+-------
   1 | hello
   2 | world
  43 | abc
(3 rows)

HTH,

Joe


Re: Question about serial vs. int datatypes

From
nolan@celery.tssi.com
Date:
> But... when converting an existing database that already has several hundred
> records in it, I can't make that field serial in PostgreSQL, can I?

I guess you haven't actually tried this yet, but if you do an insert
with an explicit value for a column of type serial, it inserts that value.
If you leave that column off the list of columns in the insert statement,
it uses the nextval of the implicit sequence, which is the default value
of the column.  If you use NULL, you will get an error.  You can also
explicitly select the sequence value.

Here's a sample table, test1.  Note the two modifiers for 'keyval'.

 Column  |         Type     |                         Modifiers

---------+------------------+----------------------------------------------
 keyval  | integer          | not null
                              default nextval('public.test1_keyval_seq'::text)
 dataval | character varying(30)

INSERT into test1 values ('15','TEST');
INSERT into test1 (dataval) values ('FISH');
INSERT into test1 values (null,'MOUSE');
INSERT into test1 values (nextval('test1_keyval_seq'),'CAT');

select * from test1;
 keyval | dataval
--------+---------
     15 | TEST
      1 | FISH
      2 | CAT
(3 rows)
--
Mike Nolan

Re: Question about serial vs. int datatypes

From
Rory Campbell-Lange
Date:
On Thu, Jun 05, 2003 at 04:05:53PM -0400, Lynna Landstreet wrote:
> But... when converting an existing database that already has several hundred
> records in it, I can't make that field serial in PostgreSQL, can I? Because
> I don't want the existing records renumbered - that would break the links
> between the different tables. But if I make the id number just a smallint
> field, then I'm stuck incrementing it manually after the conversion. Is
> there any way around this? Any way to import the existing records with their
> id number intact, and then have it switch to serial after that for new
> records?

Make a new table with a serial type field and then do a \d on that table. You will see that the default value for the
fieldis the next value from the relevant (autocreated) sequence. If you specify a value for the "SERIAL" type field,
thefield will be filled with that rather than a value from the sequence.  

Note that if you do this you need to reset the value of the current sequence. Use something like setval(sequencename)
tomax(your_serial_field). 

Rory

Re: Question about serial vs. int datatypes

From
Lynna Landstreet
Date:
Thanks to everyone who replied to this question, as well as my other one
about special characters. I'm now busily reading up on sequences and
localization. :-)


Lynna
--
Resource Centre Database Coordinator
Gallery 44
www.gallery44.org