1. Trang chủ
  2. » Công Nghệ Thông Tin

SQL PROGRAMMING STYLE- P33 docx

5 166 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 5
Dung lượng 82,76 KB

Nội dung

3.13 Every Table Must Have a Key to Be a Table 57 When I get a passport, I need a birth certificate and fingerprinting. There is a little less trust here. When I get a security clearance, I also need to be investigated. There is a lot less trust. A key without a verification method has no data integrity and will lead to the accumulation of bad data. 6. Simplicity . A key should be as simple as possible, but no simpler. People, reports, and other systems will use the keys. Long, complex keys are more subject to error; storing and transmitting them is not an issue anymore, the way it was 40 or 50 years ago. One person’s simple is another person’s complex. For an example of a horribly complex code that is in common international usage, look up the International Standard Bank Number (IBAN). A country code at the start of the string determines how to parse the rest of the string, and it can be up to 34 alphanumeric characters in length. Why? Each country has its own account numbering systems, currencies, and laws, and they seldom match. In effect, the IBAN is a local banking code hidden inside an international standard (see http:// www.ecbs.org/iban/iban.htm and the European Committee for Banking Standards Web site for publications). More and more programmers who have absolutely no database training are being told to design a database. They are using GUIDs, IDENTITY, ROWID, and other proprietary auto-numbering features in SQL products to imitate either a record number (sequential file system mindset) or OID (OO mindset) because they don’t know anything else. This magical, universal, one-size-fits-all numbering is totally nonrelational, depends on the physical state of the hardware at a particular time, and is a poor attempt at mimicking a magnetic tape file system. Experienced database designers tend toward intelligent keys they find in industry-standard codes, such as UPC, VIN, GTIN, ISBN, and so on. They know that they need to verify the data against the reality they are modeling. A trusted external source is a good thing to have. The reasons given for this poor programming practice are many, so let me go down the list: 58 CHAPTER 3: DATA DECLARATION LANGUAGE Q: Couldn’t a natural compound key become very long? A1: So what? This is the 21st century, and we have much better computers than we did in the 1950s when key size was a real physical issue. What is funny to me is the number of idiots who replace a natural two- or three-integer compound key with a huge GUID, which no human being or other system can possibly understand, because they think it will be faster and easy to program. A2: This is an implementation problem that the SQL engine can handle. For example, Teradata is a SQL designed for very large database (VLDB) applications that use hashing instead of B-tree or other indexes. They guarantee that no search requires more than two probes, no matter how large the database. A tree index requires more and more probes as the size of the database increases. A3: A long key is not always a bad thing for performance. For example, if I use (city, state) as my key, I get a free index on just (city). I can also add extra columns to the key to make it a super-key when such a super- key gives me a covering index (i.e., an index that contains all of the columns required for a query, so that the base table does not have to be accessed at all). Q: Can’t I make things really fast on the current release of my SQL software? A1: Sure, if I want to lose all of the advantages of an abstract data model, SQL set-oriented programming, carry extra data, and destroy the portability of code. Look at any of the newsgroups and see how difficult it is to move the various exposed physical locators in the same product. The auto-numbering features are a holdover from the early SQLs, which were based on contiguous storage file systems. The data was kept in physically contiguous disk pages, in physically contiguous rows, made up of physically contiguous columns. In short, just like a deck of punchcards or a magnetic tape. Most programmers still carry that mental model, too. But physically contiguous storage is only one way of building a relational database, and it is not the best one. The basic idea of a relational database is that the user is not supposed to know how or where things are stored at all, much less write code that depends on the particular physical representation in a particular release of a particular product on particular hardware at a particular time. The first practical consideration is that auto-numbering is proprietary and nonportable, so you know that you will have maintenance problems 3.13 Every Table Must Have a Key to Be a Table 59 when you change releases or port your system to other products. Newbies actually think they will never port code! Perhaps they only work for companies that are failing and will be gone. Perhaps their code is such a disaster that nobody else wants their application. But let’s look at the logical problems. First, try to create a table with two columns and try to make them both auto-numbered. If you cannot declare more than one column to be of a certain data type, then that thing is not a data type at all, by definition. It is a property that belongs to the physical table, not the logical data in the table. Next, create a table with one column and make it an auto-number. Now try to insert, update, and delete different numbers from it. If you cannot insert, update, and delete rows, then it is not really a table by definition. Finally, create a simple table with one hidden auto-number column and a few other columns. Use a few statements like: INSERT INTO Foobar (a, b, c) VALUES ('a1', 'b1', 'c1'); INSERT INTO Foobar (a, b, c) VALUES ('a2', 'b2', 'c2'); INSERT INTO Foobar (a, b, c) VALUES ('a3', 'b3', 'c3'); Put a few rows into the table and notice that the auto-numbering feature sequentially numbered them in the order they were presented. If you delete a row, the gap in the sequence is not filled in, and the sequence continues from the highest number that has ever been used in that column in that particular table. This is how we did record numbers in preallocated sequential files in the 1950s, by the way. A utility program would then pack or compress the records that were flagged as deleted or unused to move the empty space to the physical end of the physical file. But we now use a statement with a query expression in it, like this: INSERT INTO Foobar (a, b, c) SELECT x, y, z FROM Floob; Because a query result is a table, and a table is a set that has no ordering, what should the auto-numbers be? The entire, whole, completed set is presented to Foobar all at once, not a row at a time. There are (n!) ways to number (n) rows, so which one do you pick? The answer has been to use whatever the physical order of the result set happened to be. That nonrelational phrase “physical order” again! 60 CHAPTER 3: DATA DECLARATION LANGUAGE But it is actually worse than that. If the same query is executed again, but with new statistics or after an index has been dropped or added, the new execution plan could bring the result set back in a different physical order. Can you explain from a logical model why the same rows in the second query get different auto-numbers? In the relational model, they should be treated the same if all the values of all the attributes are identical. Using auto-numbering as a primary key is a sign that there is no data model, only an imitation of a sequential file system. Because this magic, all-purpose, one-size-fits-all pseudo identifier exists only as a result of the physical state of a particular piece of hardware, at a particular time, as read by the current release of a particular database product, how do you verify that an entity has such a number in the reality you are modeling? People run into this problem when they have to rebuild their database from scratch after a disaster. You will see newbies who design tables like this: CREATE Drivers (driver_id AUTONUMBER NOT NULL PRIMARY KEY, ssn CHAR(9) NOT NULL REFERENCES Personnel(ssn), vin CHAR(17) NOT NULL REFERENCES Motorpool(vin)); Now input data and submit the same row a thousand times or a million times. Your data integrity is trashed. The natural key was this: CREATE Drivers (ssn CHAR(9) NOT NULL REFERENCES Personnel(ssn), vin CHAR(17) NOT NULL REFERENCES Motorpool(vin), PRIMARY KEY (ssn, vin)); Another problem is that if a natural key exists (which it must, if the data model is correct), then the rows can be updated either through the key or through the auto-number. But because there is no way to reconcile the auto-number and the natural key, you have no data integrity. To demonstrate, here is a typical newbie schema. I call them “id-iots” because they always name the auto-number column “id” in every table. 3.13 Every Table Must Have a Key to Be a Table 61 CREATE TABLE Personnel (id AUTONUMBER NOT NULL PRIMARY KEY,—false key ssn CHAR(9) NOT NULL,—real key ); INSERT INTO Personnel VALUES ('999999999', ); Now change a row in Personnel, using the “id” column: UPDATE Personnel SET ssn = '666666666' WHERE id = 1; or using the natural key: UPDATE Personnel SET ssn = '666666666' WHERE ssn = '999999999'; But when I rebuild the row from scratch: BEGIN ATOMIC DELETE FROM Personnel WHERE id = 1; INSERT INTO Personnel VALUES ('666666666', ); END; What happened to the tables that referenced Personnel? Imagine a company bowling team table that also had the “id” column and the “ssn” of the players. I need cascaded DRI actions if the “ssn” changes, but I only have the “id,” so I have no idea how many “ssn” values the same employee can have. The “id” column is at best redundant, but now we can see that it is also dangerous. Finally, an appeal to authority, with a quote from Dr. Codd (1979): “Database users may cause the system to generate or delete a surrogate, but they have no control over its value, nor is its value ever displayed to them. This means that a surrogate ought to act like an index: created by the user, managed by the system, and never seen by a user. That means never used in queries, DRI, or anything else that a user does. . really fast on the current release of my SQL software? A1: Sure, if I want to lose all of the advantages of an abstract data model, SQL set-oriented programming, carry extra data, and destroy. faster and easy to program. A2: This is an implementation problem that the SQL engine can handle. For example, Teradata is a SQL designed for very large database (VLDB) applications that use hashing. database. They are using GUIDs, IDENTITY, ROWID, and other proprietary auto-numbering features in SQL products to imitate either a record number (sequential file system mindset) or OID (OO mindset)

Ngày đăng: 06/07/2014, 23:20