[Crap -- posted this as a new topic, too. Someone please delete that one? My apologies.]
First of all, if you're going to tell people to use correct vocabulary, you should get it right yourself. Columns, rows, and tables are all terms borrowed from the spreadsheet world. The only one you avoided using was 'cell', and used 'field' instead. You are correct that there is no order to them, but in spreadsheets, there is -- which is why re-using the same terms is a bad idea.
Database values, database variables, database domains (headers).
Relation values, relation variables, relation domains (headers), relation body.
Tuple values, tuple variables, tuple domains (headers).
Attributes, domains, values.
Those are the terms you should be using. A database value is a named set of relation variables. A relation variable always has a value that is a set of tuples whose headers all match the relation variable's type's header. And so forth.
But do we care? No.
As to autonumber fields, Alex, you're again wrong. They're called surrogate keys -- that is, candidate keys added to a relation in order to simplify things. You may have any number of candidate keys on a relation header, each with any number of fields. Each one is its own unique constraint on the tuples of the relation's body. One of them is picked (usually, but optionally) as the primary key. If you do pick one as a primary key, you'll use those same attributes in all referencing relations. But you're not required to. If you have two different unique ways of addressing a row, you can use either of them, interchangibly, anywhere in the database. An autonumber field is just one example of defining a surrogate key, that is, an invented candidate key.
Codd's rules require that any value in the database be addressable by the relation variable name and values for at least one candidate key, plus the attribute name for which you want to retrieve the value. The idea was that everything was "out in the open". You can see autonumber values, you can manipulate them. They are not the same thing as pointers, which are hidden and opaque.
In CODASYL, pointers were external to the tuple, not internal. When you had a tuple, you didn't have the pointer -- the pointer was not part of the information. It was physical, not logical. You had to follow pointers around to get rows. That's not what autonumbers are about. When you get a tuple from a relation that uses autonumbers, you have the number. It's part of the information. Nothing is hidden. You can change that number without breaking pointers -- most database systems will automatically update all FK fields for you, though that's not required. What is required is merely that the database system enforce constraints, and in the case of FK's, that should be "values of these attributes must match values of those attribtes". That is, a DBMS is only required to reject a COMMIT if you change the PK of a row currently referenced elsewhere. The rest is kindness.
In CODASYL, you had to navigate the records by following pointers around between rows in various tables. A master row would maintain a pointer into its first child, the children would have pointers to each other, and then there'd be another pointer back to the master row. That's what pointers are about. Order, physical, opaque. With autonumbers, we're talking about "find where this is true" -- no order, no physical aspect, and it's not opaque. It's a key, not a pointer.
The problem you described wasn't a problem of autonumbers at all. The problem was the rest of the code. You failed to maintain a proper set of candidate keys on your lookup tables -- one for the surrogate (autonumber) attribute, yes, but another for the text attribute that was being changed. Don't blame autonumbers for your mistakes. Autonumbers don't naturally lead to data corruption as such. If you forget to properly model the rest of the data, then yes, there can be problems -- but that'd be the case regardless. (Actually, someone else reading your description understands you to have been making entire copies of the lookup table, under a different name each time? If so, you were -way- off course, and I'm not sure I can properly explain how much.)
While speaking of misunderstanding about the relational model, we should also address the CSV point you brought up earlier. CSV attributes are, in fact, allowed by the relational model. The requirement is merely that they be treated atomically. That is, the value "A,B,C" is not the same as the value "A,B", and any tuples containing such a value are just one tuple each, not two or three. The relational model does not, however, prevent you from defining functions such as IS_SUBSET_OF that would allow you to do joins between relations across CSV columns, if you should so desire. You should be able to do, for example, SELECT A.*, B.* FROM A INNER JOIN B ON IS_SUBSET_OF(B.FIELD_B, A.FIELD_A);. The requirement merely prohibits you from treating a single tuple as if it were several, automatically breaking up a CSV attribute into non-CSV values for several virtual tuples. In fact, a lot of work has gone into making sure the relational model is properly understood to allow complex types, not just 'text', 'date', and 'integer'. Arrays, sets, images, polygon descriptions, etc. are all theoretically allowed, so long as you define proper functions for manipulating them. CSV is just one such example, albeit probably a slow one. (CSV is mainly human-readable -- you could come up with slightly better general-purpose set or array types to use.)
Autonumbers are:
a) faster, in many cases, than comparing text values
b) smaller, less footprint
c) allowed by relational theory
d) single field vs. multi-field FK's, thus faster
e) allow you to change uniqueness constraints in the referenced relation without changing the headers for every referencing relation -- particularly useful when requirements change slightly or previously-unknown outlier cases are discovered
You should always remember to add proper constraints to the referenced relation, of course. But there's more to constraints than merely using a primary key built out of existing attributes; making sure sums remain positive, that things balance, that certain dates always maintain a certain relationship between them (date_of_death > date_of_birth, for example), etc.
I've seen people try to get by without autonumbers when they had improperly identified candidate keys. Relations with 16 fields making up the primary key -- and they were lucky, this particular system allowed NULL states for attributes in the primary key (this is normally a bad thing, as NULL != NULL, which should make such rows impossible to address.) Despite this, we still had cases where we needed to enter two tuples with the same PK value, as distinct tuples. And it creates a mess -- every relation referencing this one now has 16 fields devoted just to that. That's a lot of data, and it's still wrong.
You fear autonumbers because of pointers, but you misunderstand the distinction. Come to think of it, if autonumbers are so evil ... why do we use, instead, autonumbers provided to use by the government? Social security numbers, federal tax id's, etc. are all just forms of autonumbers in their database. And on top of that, theirs aren't necessarily unique. (There have been documented cases of two people having the same SSN and DOB, yet being entirely unrelated otherwise. Don't trust SSN to be unique.)
Grab a copy of 'Foundation for Object/Relational Databases -- The Third Manifesto' (C.J. Date and Hugh Darwen) if you haven't already. They'll clear up your misconceptions for you, though they'll add a few too (their opinions on inheritance should be ignored, for example.) The relational model has fewer requirements than many people believe, and is therefore much more flexible than they've thought.