views:

208

answers:

4

The first normal form says that row ordering should not matter. Does this mean that a table with date as part of the key is not 1NF? e.g. Consider a table of ticker prices where date/time is part of the PK. In this case, you get the last price by ordering the data by date and selecting the top 1 row. Does this mean that for to fulfill 1NF you need to split the table into: 1) TickerCurrentPrice (1 row per ticker) 2) TickerHistoricalPrice Thanks

A: 

No. It means that there is no intrinsic order. If you want the date of the last price you have to select max(date) from your table.

kmkaplan
+2  A: 

No, "select... order by..." does not violate 1NF. Row (and column) ordering which violates 1NF is more about the situations along the lines of "select * from XYZ; and then pick the third row from top and fourth column from left". Yes, I have seen DB designs like that.

Mart Oruaas
However, to get current price I have todo a "pick", by selecting the top 1 after ordering... From your example then my table is not 1NF?
LongboatHarry
Not exactly, see Quassnoi's excellent answer.
Mart Oruaas
+3  A: 

1NF is aspect of a table representing a relation, not of a table as such.

If your relation says ticket HAS price, that it's a 1NF violation, as you cannot determine if a ticket HAS or HAS NOT the price by looking on a single record. You'll need to fetch all prices on this ticket and select last of them, which violates the non-ordering rule of the 1NF.

If your relation says ticket HAD BEGUN TO COST price ON date, then it's in the 1NF all right, because each record says what it says: this ticket costs this price from this date.

Thus, we say that this table does not comply with the 1NF when representing the first relation, but does comply when representing the second one.

The table itself remains the same, of course.

It doesn't necessary mean though that you need to split your tables.

The whole point of relational databases is that you can use relational operators to convert one relation to another.

What is a relation in terms of the RDBMS? It's a table showing all combinations of all possible values that are in this relation between theirselves.

For instance, if we need to construct equality relation on natural numbers from 1 to 5, we have this table:

1 1
2 2
3 3
4 4
5 5

All pairs that appear in this table are in equality relation; all pairs that don't appear, are not. We don't see (2, 3) here, or (4, 5), as they are not equal.

But you don't need to keep the whole pair in the database. You keep single values instead and write a query:

SELECT n1.number, n2.number
FROM number n1, number n2
WHERE n1.number = n2.number

, which gives you the same result.

Actually, normal forms let you keep simplest possible relation tables in the database and construct more complex relations from them using SQL queries.

In your case, if you write a query (or define a view) in the following way:

SELECT ticket, price
FROM mytable
WHERE (ticket, date) IN (
  SELECT ticket, MAX(date)
  FROM mytable
  GROUP BY
    ticket
  )

, you get relation (ticket HAS price) from (ticket HAD BEGUN TO COST price ON date) exactly as if you were keeping the whole table in the database.

Quassnoi
This is kind of what I was thinking. Because the table is being used to express 2 different relations (HAS and HAD) then it should be split into one table for the current price, and another table for all historical prices.
LongboatHarry
Not exactly, see updated post.
Quassnoi
Thanks for this very thorough answer. Fully understand now with your help - and have learnt alot thinking it through. Thanks again.
LongboatHarry
+1  A: 

What is meant is that the if some ordering of the data (like by date) is to be recorded then it should be recorded explicitly, e.g. in a date column. What would be wrong would be to have the ordering only implicit in the physical order of the rows on disk (assuming you could control that anyway). In other words, you have to ORDER BY some column to get the data back in that order.

Tony Andrews