Question

I want to make a composite key (well that's the idea but I'm open to other suggestions) on a Documents table. It would consist of two columns, year (2010,...) and an ID, which would be autoincrementing but it should restart itself every year.

So keys like these 2010-1, 2010-2, ..., 2011-1, 2011-2, ... and, preferrably those keys should also be used for displaying, printing and searching.

Though I don't believe autoincrementing will work, because of the reset every year, so I guess I'll have to make increments myself, won't I?

Or should I just make a varchar column and construct each key myself and just put a unique on that column?

So, what are my options?

Please also take in consideration future design issues that I might have with a chosen design whatever would it be and ease of querying.

UPDATE:

I'm really starting to look into letting the application construct the key and provide it when inserting. However, it would require looking into DB for the last issued ID, which could result in problems in high volume usage.

Was it helpful?

Solution

It is a good practice to separate business with data storage structure. Why? Because tomorrow somebody will decide to change business logic:

  • use non-integer document order (1-AA, 1-AB, 1-AC...)
  • include year and month to build some monthly reports
  • any other changes...

And what should you do than?

So, my solution is:

  • use primary key (int, for example or your preferred data type) to do relationship with other tables in the database
  • use business key 1.2.3...as you wish (maybe some identifier generator)
  • use datetime field to store date of adding document, the year you can calculate dynamically.

OTHER TIPS

Why not add an actual auto-incrementing id? Composite keys can quickly grow to where they're virtually useless - especially for performance reasons if you ever have to join on the table. If you then ALSO want to log that Document XYZ was the first document stored in 2010, you could still have your Year and Order (or whatever) columns, but your primary key stays nice and clean.

If you're going to the trouble of creating an auto-incrementing key, I would throw out the idea of resetting it on every year, and just use an IDENTITY INT column instead.

If you want to get the sequence number of the document within the year, there are SQL functions you can use to do that:

ROW_NUMBER() OVER (PARTITION BY ... ORDER BY...)

Though I don't believe auto-incrementing will work, because of the reset every year, so I guess I'll have to make increments myself, won't I?

Yep.

I recommending adding a column in order to generate the resetting value. An IDENTITY column would be best; a DATETIME could hold the record creation time but transactions within 3.33 milliseconds (0. 00333 seconds) of each other would have the same timestamp.

Either way, you could generate the id value using:

SELECT (SELECT COUNT(*)
          FROM DOCUMENTS t
         WHERE t.year = d.year
           AND t.col <= d.col) AS id,
        d.year
   FROM DOCUMENTS d

Or if you're on SQL Server 2005+, you could use:

 SELECT ROW_NUMBER() OVER (PARTITION BY d.year ORDER BY d.col) AS id,
        d.year
   FROM DOCUMENTS d
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top