WHAT’S A TUPLE?

Is this a tuple?—

SNO | CHAR

SNAME | CHAR

STATUS | INTEGER

CITY | CHAR

S1

Smith

20

London

Well, no, it isn’t—it’s a picture of a tuple, not a tuple as such (and note that for once I’ve included the type names in that picture as well as the attribute names). As we saw in Chapter 1, there’s a logical difference between a thing and a picture of a thing, and that difference can be very important. For example, tuples have no left to right ordering to their attributes, and so the following is an equally good (bad?) picture of the very same tuple:

STATUS | INTEGER

SNAME | CHAR

CITY | CHAR

SNO | CHAR

20

Smith

London

S1

Thus, while I’ll certainly be showing many pictures like these in the pages to follow, please keep in mind that they’re only pictures, and they can sometimes suggest some things that aren’t true.

With that caveat out of the way, I can now say exactly what a tuple is:

Definition: Let T1, T2, ..., Tn (n ≥ 0) be type names, not necessarily all distinct. Associate with each Ti a distinct attribute name, Ai; each of the n attribute-name/type-name combinations that results is an attribute. Associate with each attribute an attribute value, vi, of type Ti; each of the n attribute/value combinations that results is a component. Then the set of all n components thus defined, t say, is a tuple value (or just a tuple for short) over the attributes A1, A2, ..., An. The value n is the degree of t; a tuple of degree one is unary, a tuple of degree two is binary, a tuple of degree three is ternary, ..., and more generally a tuple of degree n is n-ary. The set of all n attributes is the heading of t.

For example, with reference to the first of the two pictures on the previous page of the tuple for supplier S1, we have:

  • Degree: 4. The heading is also said to have degree 4.

  • Type names (as shown in the picture, left to right): CHAR, CHAR, INTEGER, CHAR.

  • Corresponding attribute names: SNO, SNAME, STATUS, CITY.

  • Corresponding attribute values: ‘S1’, ‘Smith’, 20, ‘London’. Note the quotes enclosing the character string values here, incidentally; I didn’t show any such quotes in the pictures, but perhaps I should have done—it would have been more correct.

    Aside: Suppose for a moment, as we did in Chapter 2, that attribute SNO was of type SNO (a user defined type) instead of type CHAR. Then it would be even more incorrect to say the SNO value in the tuple we’re talking about was S1, or even ‘S1’; rather, it would be SNO(‘S1’). A value of type SNO is a value of type SNO, not a value of type CHAR!—a difference in type is certainly a logical difference. (Recall from Chapter 2 that the expression SNO(‘S1’) is a selector invocation—in fact, a literal—of type SNO.) End of aside.

  • Heading: The easiest thing to do here is show another picture:

    SNO | CHAR

    SNAME | CHAR

    STATUS | INTEGER

    CITY | CHAR

    Of course, this picture represents a set, and the order of attributes is arbitrary. Here’s another picture of the same heading:

    STATUS | INTEGER

    SNAME | CHAR

    CITY | CHAR

    SNO | CHAR

    Exercise: How many different pictures of this same general nature could we draw to represent this same heading? (Answer: 4! = 4 * 3 * 2 * 1 = 24.)[39]

Now, a tuple is a value; like all values, therefore, it has a type (as we know from Chapter 2), and that type, like all types, has a name. In Tutorial D, such names take the form TUPLE {H}, where {H} is the heading. In our example, the name is:

     TUPLE { SNO CHAR , SNAME CHAR , STATUS INTEGER , CITY CHAR }

(but the order in which the attributes are specified is arbitrary).

To repeat, a tuple is a value. Like all values, therefore, it must be returned by some selector invocation (a tuple selector invocation, naturally, if the value is a tuple). Here’s a tuple selector invocation for our example (Tutorial D again)

     TUPLE { SNO 'S1' , SNAME 'Smith' , STATUS 20 , CITY 'London' }

(where the order in which the components are specified is again arbitrary). Observe that in Tutorial D each component is specified as just an attribute-name/expression pair, where the specified expression denotes the corresponding attribute value; the attribute type is omitted because it can always be inferred from the type of the specified expression.

Here’s another example (unlike the previous one, this one isn’t a literal, because not all of its arguments are specified as literals in turn):

     TUPLE { SNO SX , SNAME 'James' , STATUS TX , CITY CX }

I’m assuming here that SX, TX, and CX are variables of types CHAR, INTEGER, and CHAR, respectively.

As these examples indicate, a tuple selector invocation in Tutorial D consists in general of the keyword TUPLE, followed by a commalist of attribute-name/expression pairs, the whole commalist enclosed in braces. Note, therefore, that the keyword TUPLE does double duty in Tutorial D—it’s used in connection both with tuple selector invocations, as we’ve just seen, and with tuple type names as we saw earlier. An analogous remark applies to the keyword RELATION also (see the section WHAT’S A RELATION? later in this chapter).

Consequences of the Definitions

Now I want to highlight some important consequences of the foregoing definitions. The first is: No tuple ever contains any nulls. The reason is that, by definition, every tuple contains a value (of the appropriate type) for each of its attributes, and (as we saw in Chapter 1) nulls aren’t values—despite the fact that SQL often, though not always, refers to them explicitly as null values. Recommendation: Since the phrase “null value” is a contradiction in terms, don’t use it; always say just “null” instead. Note that this recommendation isn’t just a matter of pedantry; rather, it’s a matter of thinking straight. SQL itself manages to make numerous mistakes in its handling of nulls, and some of those mistakes can be traced directly to the fact that SQL does sometimes, but not always, think of null as a value. (Indeed, this ambivalence is reflected in the standard’s very definition of the concept, which reads as follows: “null value: A special value that is used to indicate the absence of any data value.” In other words: Null is a value that means there isn’t a value.)

Now, if no tuple ever contains any nulls, then no relation does so either, a fortiori; so right away we have at least a formal reason for rejecting the concept of nulls—but in the next chapter I’ll give some much more pragmatic reasons as well.

The next consequence—or pair of consequences, rather—is: Every subset of a tuple is a tuple and every subset of a heading is a heading. (I did mention these points in Chapter 1, but now I want to elaborate on them.) By way of example, given our usual tuple for supplier S1, what we might call “the {SNO,CITY} value” within that tuple is itself another tuple (of degree two):

SNO | CHAR

CITY | CHAR

S1

London

Its heading is as indicated, and its type is TUPLE {SNO CHAR, CITY CHAR}. Likewise, the following is a tuple also:

SNO | CHAR

S1

This tuple is of degree one, and its type is TUPLE {SNO CHAR}.

Now, as I’m sure you know, the empty set—i.e., the set that contains no elements—is a subset of every set. It follows that the empty heading is a valid heading!—and hence that a tuple with an empty set of components is a valid tuple (though it’s a little hard to draw pictures of such a tuple on paper, and I’m not even going to try). A tuple with an empty heading has type TUPLE {}; indeed, we sometimes refer to it explicitly as a 0-tuple, in order to emphasize the fact that it has no components and is of degree zero. We also sometimes call it an empty tuple. Now, you might think such a tuple is unlikely to be of much use in practice; in fact, however, it turns out, perhaps rather surprisingly, to be of crucial importance. I’ll have more to say about it in the section TABLE_DUM AND TABLE_DEE, later.

Let’s get back to the original tuple for supplier S1 (i.e., the one of degree four) for a moment. Suppose we’re given that tuple and we want to access the actual value of some attribute, say the SNO attribute, from that tuple. Then we have to extract that value, somehow, from the tuple that contains it. Tutorial D uses syntax of the form SNO FROM t for this purpose (where t is any expression that denotes a tuple with an SNO attribute). SQL uses dot qualification: t.SNO.

Note: It follows from the foregoing paragraph that a value v and a tuple t that contains just that value v aren’t the same thing; in particular, they’re of different types. This logical difference is analogous to that described in Chapter 2, between a tuple t and a relation r that contains just that tuple t; these aren’t the same thing either (they too are of different types).

Now I’d like to turn to the notion of tuple equality. (Again I mentioned this notion in Chapter 1, but now I want to elaborate on it.) Recall first from Chapter 2 that the “=” comparison operator is—in fact, must be—defined for every type, and tuple types are no exception. Basically, two tuples are equal if and only if they’re the very same tuple (just as, for example, two integers are equal if and only if they’re the very same integer). But it’s worth spelling out the semantics of tuple equality in detail, since so much in the relational model depends on it—for example, candidate keys, foreign keys, and almost all of the operators of the relational algebra are defined in terms of it. Here then is a precise definition:

Definition: Tuples t and t′ are equal if and only if they have the same attributes A1, A2, ..., An—in other words, they’re of the same type—and, for all i (i = 1, 2, ..., n), the value v of Ai in t is equal to the value v′ of Ai in t′.

Also (to repeat from Chapter 1, this might seem obvious, but it needs to be said), two tuples are duplicates of each other if and only if they’re equal. Thus, e.g., the tuple for supplier S1 in the suppliers relation of Figure 1-3 is equal to, and is therefore a duplicate of, itself—and it isn’t equal to, or a duplicate of, anything else (any other tuple in particular).

By the way, it’s an immediate consequence of the foregoing definition that all 0-tuples are duplicates of one another. For this reason, we’re within our rights if we talk in terms of the 0-tuple instead of “a” 0-tuple, and indeed we usually do. Note, moreover, that we can validly say that the 0-tuple is a subset of every tuple (just as we can say the empty set is a subset of every set).

So the comparison operator “=”, and therefore the comparison operator “≠” also, do both necessarily apply to tuples. However, the operators “<” and “>” do not apply. The reason is that tuples are fundamentally sets (sets of components, to be specific), and such operators make no sense for sets.

In closing this section, let me draw your attention to Exercise 3.16 at the end of the chapter (also the discussion of that exercise in Appendix F), which I strongly recommend you devote some thought to. Later chapters in the book will appeal to some of the points raised by that exercise.



[39] More generally, the expression n! (which is read as either “n factorial” or “factorial n” and is often pronounced “n bang”) is defined as the product n * (n−1) * ... * 2 * 1.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.60.232