in reply to Re^3: Auto-Increment and DBD Agnosticism
in thread Auto-Increment and DBD Agnosticism

Most systems of this nature rely on the primary key as the natural unique identifier, I would really suggest you stick with that, and subclass for different DBDs.

I'm not sure that I entirely agree with that. It's legitimate to have another unique identifier. You just don't want to be using it as a foreign key in another table. The argument for having surrogate primary keys is that they are meaningless as anything except a row identifier, having no semantic meaning as far as your data is concerned, and thus are non-volatile and consequently safe to use for linking objects/rows together.

I agree with your assertion that subclassing is the right thing to do. I just don't think that the primary key has to be the only unique identifier. For example, think of a user table... The user id is going to be unique. It would be a bad idea to use it as a foreign key in link tables, but it would be unique all the same.

Anyway, I'm not sure what I'm arguing anymore... I didn't get enough sleep last night and am not entirely coherent. :-)

  • Comment on Re^4: Auto-Increment and DBD Agnosticism

Replies are listed 'Best First'.
Re^5: Auto-Increment and DBD Agnosticism
by stvn (Monsignor) on Jun 24, 2004 at 13:59 UTC
    For example, think of a user table... The user id is going to be unique. It would be a bad idea to use it as a foreign key in link tables, but it would be unique all the same

    Quite true, but that is what I mean about "another uniqueness constraint". Personally, I usually call this "user_name" and have "user_id" be a auto increment primary key :).

    The only reason I keep pushing this idea is that I have been bitten by it in the past. And in a OO-relational mapping class as well (although it was a custom class, and not a full system like yours). In the end I wrote a DBI wrapper which handled the differences between MySQL's 'last_insert_id' and PostgreSQL's 'pg_oid_status' which gave me a basic level of DBD agnosticism (well at least the DBD's I cared about that is).

    Anyway, I'm not sure what I'm arguing anymore... I didn't get enough sleep last night and am not entirely coherent. :-)

    Two words: Mountain Dew :)

    -stvn
      The only reason I keep pushing this idea is that I have been bitten by it in the past. And in a OO-relational mapping class as well (although it was a custom class, and not a full system like yours). In the end I wrote a DBI wrapper which handled the differences between MySQL's 'last_insert_id' and PostgreSQL's 'pg_oid_status' which gave me a basic level of DBD agnosticism (well at least the DBD's I cared about that is).

      I'm wondering how much stuff from my Whatever::Object::save method needs to be pushed into the subclass. One possibility is just to have each subclass define an "extract_insert_id" method that gets invoked from inside Whatever::Object::save and takes the statement handle as an argument, returning $sth->{whatever} as appropriate to the DBD in question. This, of course, makes the assumption that auto-incrementation will be available in all databases, and that it will be provided via the statement handle. Another possibility is that the entire Whatever::Object::save method should be pushed into subclasses, since there is the possibility that I'll have to generate random primary keys and specify them as part of an insert, in the case of databases that don't do auto-increment.

      I guess its a question of how much I care... What databases don't support auto-increment fields? Alas, my experience is limited solely to MySQL.

        I'm wondering how much stuff from my Whatever::Object::save method needs to be pushed into the subclass.

        Thats the beauty of subclasses, you don't need to answer that question now. You should be sure to design your base class with small methods which each represent a single unit of work. This way the subclasser only needs to override as little as nessecary. Also, throw out the idea that your subclass writers will be able to write their subclasses without reading and understanding the base class. Its overly idealic to think that is possible (at least in most cases).

        I guess its a question of how much I care...

        Well, thats a good question. You should care as much as you have time to. Since you are writing this for your own (and your companies) purposes, then you should focus on that aspect of it first and formost. You will drive yourself nuts trying to write something that works for everything. Just get a solid MySQL subclass working, and leave the issues of other DBD's aside for now. If when you go to add PostgreSQL support, and you need to munge with the internals of Whatever::Object, you can do that. If your classes are designed well, then it won't ever matter to the end user what you do to the objects internals.

        What databases don't support auto-increment fields? Alas, my experience is limited solely to MySQL.

        Well, my experience is mostly with MySQL too. I have done some limited work with PostgreSQL, which doesn't directly support AUTO_INCREMENT as a keyword, but can be emulated by using the SEQUENCE type instead. I have also messed around with MS Access and MS SQL Server, but that was a while ago and I had no clue what I was doing anyway. In general I think there will almost always be some way of creating an AUTO_INCREMENT-like column for the primary key. Again, I would say don't worry about DBD specific stuff outside of MySQL until you actually need to use it. If MySQL works good, then you have covered a sizable percentage of the population anyway, and that is a good start.

        -stvn