Live data from Hacker News

What does First Normal Form mean?

cargocultcode.com

21–30 of 125 posts

Re: What does First Normal Form mean?

#21
post #11

Earlier quoted context omitted.

What about people with the same birthdays?

What about them? Do they really exist, practically speaking? At a quick glance on my databases, I see nothing of the sort.

I share the same name and birthdate as another individual. It has actually caused me to be held up at the border before.

Re: What does First Normal Form mean?

#22
post #8

I think he contradicts himself and confuses the data with the information. I don't think delimited values representing a table in a column can be considered normalized. > Make no mistake, encoding multiple values in a single string is generally a bad design. But it has nothing to do with first normal form. First normal form mean a column should not allow relations as values. A comma-separated string is still just a s…

No, is not a contradiction.

Is like say "Is wrong to store a large json in a cell in an array, that make it not an array".

A relation is A VALUE. That is.

The atomicity of the data INSIDE each "cell" is orthogonal to the fact the that relation is a relation.

This is the point.

Re: What does First Normal Form mean?

#23
post #11

Earlier quoted context omitted.

What about them? Do they really exist, practically speaking? At a quick glance on my databases, I see nothing of the sort.

I share the same name and birthdate as another individual. It has actually caused me to be held up at the border before.

What gave proof that you were not this individual in the end?

Re: What does First Normal Form mean?

#25
post #22
post #8

I think he contradicts himself and confuses the data with the information. I don't think delimited values representing a table in a column can be considered normalized. > Make no mistake, encoding multiple values in a single string is generally a bad design. But it has nothing to do with first normal form. First normal form mean a column should not allow relations as values. A comma-separated string is still just a s…

No, is not a contradiction. Is like say "Is wrong to store a large json in a cell in an array, that make it not an array". A relation is A VALUE. That is. The atomicity of the data INSIDE each "cell" is orthogonal to the fact the that relation is a relation. This is the point.

For even more fun mind bending, there's absolutely nothing that violates the relational model in having relation-valued attributes. SQL doesn't support that, but that doesn't mean its non-relational.

Re: What does First Normal Form mean?

#26

I have never understood why RDBs have such general concepts of primary keys, where you can for example let date of birth be a primary key, when in every schema I have ever designed or seen, all rows get unique integer IDs anyway.

> when in every schema I have ever designed or seen, all rows get unique integer IDs anyway.

This is artifact of 4 things:

- Indexed Integer search are fast in RDBMS

- Having an non-bussines related value for identify a row could save you from making triggers for updated in other relations if it change. This is the part a lot of folks missed: If you already have a natural PK and it not change, is wasteful add ANOTHER (is another index btw)

- Is enforced by ORMS that are badly designed.

- Most people have not idea how model a database, and this one little thing is one of the easier "fix" you can think of!

I have done a lot "non integer primary keys" before (and not GUIds!) and is useful that RDBMS are not like mongo with a fixed schema (yes! Mongo is a single fixed-schema for all your data!).

For reporting, store aggregates, pre-compute values, etc is very valuable!

For example, in accounting you do reports per day/mont/year.

You then do granularity per day, and the another per month, per year, per semestre, etc. When the data volume is high, making tables "days, months, years" make a lot of sense.

Cool guys call this a "time-series database".

But the rdbms CAN model it!

And can model

- "document database"

- "key-value database"

- "olap database"

- "columnar database"

etc.

(you go for specialized backend for performance but honestly? Most of the time is a mistake if them are not relational.

"Relational" don't means "is backed by b-trees, is row oriented and use SQL")

Re: What does First Normal Form mean?

#27
post #22
post #8

I think he contradicts himself and confuses the data with the information. I don't think delimited values representing a table in a column can be considered normalized. > Make no mistake, encoding multiple values in a single string is generally a bad design. But it has nothing to do with first normal form. First normal form mean a column should not allow relations as values. A comma-separated string is still just a s…

No, is not a contradiction. Is like say "Is wrong to store a large json in a cell in an array, that make it not an array". A relation is A VALUE. That is. The atomicity of the data INSIDE each "cell" is orthogonal to the fact the that relation is a relation. This is the point.

[deleted]

Re: What does First Normal Form mean?

#29
> A relation more or less correspond to a table

"More or less", but mostly less. Views are relations. The rowsets returned by a SELECT query are relations. Etc.

Without going into what relational algebra is about, I find it a lot more helpful to understand a "relation" like this:

A relational database is like a Prolog interpreter: it's a thing that "knows" a bunch of "facts", because someone has "asserted" (declared to be true) those facts to it.

In Prolog, facts look like this:

• red(MyCar).

• father(HarryPotter, JamesPotter).

• succ(1, 2).

Those look like functions, but what they really are, are tuples, and moreover, tuples that are members of a relation. They describe / assert a particular relationship. The "function name" at the beginning of a fact is the label, an identifier for a particular kind of relationship known to the system; it is then followed by an N-tuple of values, describing the details of this particular instance of the relationship.

A mathematical "relation", then, can be understood as an arbitrary set containing facts/relationships of a given type (the "type" being the predicate label, the tuple's arity, and the domain types of the tuple's slots.)

Note that what this definition is defining is, essentially, an ADT. A relation is a container for relationships, that exposes certain operations (relational algebra).

You can think of the set of "asserted" facts/relationships of each kind, as being a special relation. A global data structure.

But remember that Prolog can derive truth from predicate functions (e.g. that 'succ' predicate above can be defined by induction by defining a base-case fact and a function succ(N, N + 1).) So, while the set of asserted facts is a relation declaring which facts/relationships are "true", it's not the only source of truth.

-----

Now, going back to the world of relational databases:

SQL is a language for manipulating relations, just as APL is a language for manipulating arrays.

Database tables are relations! But they're not the only relations in the DB. Any "rowset" (as Postgres terms it) that you create or manipulate is a relation.

Every relation in an RDBMS (table, view, result rowset, etc.) has a type. That type is the kind of its relation, as defined above. It includes the arity and types of the tuple fields, yes, but also the label.

    -- Prolog equivalent relation type: foo(A, B).
    CREATE TABLE foo (a text, b text).
When you're creating an RDBMS table with CREATE TABLE, and giving a structural inline row-type definition, you're implicitly first defining a relation type with the same label as the table's name. The table itself is now just one relation of that type. You can have others! (In fact, queries selecting * from that table, are already other relations of the same type. However, if you're projecting or joining — changing the shape of the result-set — then your result relation is of a new temporary relation type.)

Perhaps surprisingly, you can have two RDBMS tables that have the same relation type, which makes them both sources of truth about the same facts. (Why? Partitions, for one.)

But two RDBMS tables aren't sources of truth about the same facts just because they share a shape. They need to actually be defined as having the same relation type (including the label!), to be considered interchangeable by the DB (for purposes of e.g. defining stored procedures that operate on rows of a given type.)

You can't do this by just creating another table with the same (structural inline) row-type definition. Those tables will have different relation types, because those types are carrying around predicate labels, and those labels are different.

    -- BAD: relation types are fathers_us(text, text) and fathers_eu(text, text). Incompatible!
    CREATE TABLE fathers_us (child text, father text);
    CREATE TABLE fathers_eu (child text, father text);
Instead, you must either explicitly define a relation type using CREATE TYPE; or reuse the type implicitly created from your first CREATE TABLE, to create the second. Only then are the relation labels the same.

    -- Single type: father(A, B).
    CREATE TYPE father AS (child text, father text);

    -- GOOD: same type father(A, B).
    CREATE TABLE fathers_us OF father;
    CREATE TABLE fathers_eu OF father;
Why don't DBMSes use structural typing? Well, because facts can have the same structure but still not be facts about the same thing:

    CREATE TABLE fathers(child text, parent text);
    CREATE TABLE mothers(child text, parent text);
A stored procedure that takes a fathers(text, text) row, shouldn't necessarily be able to accept a mothers(text, text) row!

Re: What does First Normal Form mean?

#30
post #22

Earlier quoted context omitted.

No, is not a contradiction. Is like say "Is wrong to store a large json in a cell in an array, that make it not an array". A relation is A VALUE. That is. The atomicity of the data INSIDE each "cell" is orthogonal to the fact the that relation is a relation. This is the point.

For even more fun mind bending, there's absolutely nothing that violates the relational model in having relation-valued attributes. SQL doesn't support that, but that doesn't mean its non-relational.

Re: DB support for relations as values — while no DB I know of supports full relations (sets of tuples) in values, composite-typed (single-tuple) columns are a thing, e.g. the on_hand example table in https://www.postgresql.org/docs/current/rowtypes.html

Also, presuming DB support for some format like JSON, you can encode a relation into a JSON value, stick it into a column and then, at query time, use a function like Postgres's json_to_recordset(json) to emit a relation (set of tuples). Postgres doesn't know how to deal with it "as is" (i.e. it forces you to treat the result of a function as a named joined table in your query, rather than treating it as an concrete value) but it does understand where it is in relation (heh) to the rest of the row, since you can unnest() values from this virtual table and get the right results out.

As awful as that sounds, we're actually doing that in production to normalize data coming from redis_fdw (which gives you, basically, (key text, value jsonb) rows for Redis hashes) into relational shape.

Post reply on HN