1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML
><HEAD
><TITLE
>Indices and Keys</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet version 1.19"><LINK
REL="HOME"
TITLE="PostgreSQL User's Guide"
HREF="user.html"><LINK
REL="PREVIOUS"
TITLE="UNION Queries"
HREF="typeconv2704.html"><LINK
REL="NEXT"
TITLE="Arrays"
HREF="arrays.html"></HEAD
><BODY
BGCOLOR="#FFFFFF"
TEXT="#000000"
><DIV
CLASS="NAVHEADER"
><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>PostgreSQL User's Guide</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="typeconv2704.html"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="arrays.html"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><H1
><A
NAME="KEYS"
>Chapter 9. Indices and Keys</A
></H1
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Author: </B
>Written by
<A
HREF="herouth@oumail.openu.ac.il"
TARGET="_top"
>Herouth Maoz</A
></P
></BLOCKQUOTE
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Editor's Note: </B
>This originally appeared on the mailing list
in response to the question:
"What is the difference between PRIMARY KEY and UNIQUE constraints?".</P
></BLOCKQUOTE
><PRE
CLASS="PROGRAMLISTING"
>Subject: Re: [QUESTIONS] PRIMARY KEY | UNIQUE
What's the difference between:
PRIMARY KEY(fields,...) and
UNIQUE (fields,...)
- Is this an alias?
- If PRIMARY KEY is already unique, then why
is there another kind of key named UNIQUE?</PRE
><P
>A primary key is the field(s) used to identify a specific row. For example,
Social Security numbers identifying a person.</P
><P
>A simply UNIQUE combination of fields has nothing to do with identifying
the row. It's simply an integrity constraint. For example, I have
collections of links. Each collection is identified by a unique number,
which is the primary key. This key is used in relations.</P
><P
>However, my application requires that each collection will also have a
unique name. Why? So that a human being who wants to modify a collection
will be able to identify it. It's much harder to know, if you have two
collections named "Life Science", the the one tagged 24433 is the one you
need, and the one tagged 29882 is not.</P
><P
>So, the user selects the collection by its name. We therefore make sure,
withing the database, that names are unique. However, no other table in the
database relates to the collections table by the collection Name. That
would be very inefficient.</P
><P
>Moreover, despite being unique, the collection name does not actually
define the collection! For example, if somebody decided to change the name
of the collection from "Life Science" to "Biology", it will still be the
same collection, only with a different name. As long as the name is unique,
that's OK.</P
><P
>So:
<P
></P
></P><UL
><LI
><P
>Primary key:
<P
></P
></P><UL
COMPACT="COMPACT"
><LI
STYLE="list-style-type: disc"
><P
>Is used for identifying the row and relating to it.</P
></LI
><LI
STYLE="list-style-type: disc"
><P
>Is impossible (or hard) to update.</P
></LI
><LI
STYLE="list-style-type: disc"
><P
>Should not allow NULLs.</P
></LI
></UL
><P> </P
></LI
><LI
><P
>Unique field(s):
<P
></P
></P><UL
COMPACT="COMPACT"
><LI
STYLE="list-style-type: disc"
><P
>Are used as an alternative access to the row.</P
></LI
><LI
STYLE="list-style-type: disc"
><P
>Are updateable, so long as they are kept unique.</P
></LI
><LI
STYLE="list-style-type: disc"
><P
>NULLs are acceptable.</P
></LI
></UL
><P></P
></LI
></UL
><P> </P
><P
>As for why no non-unique keys are defined explicitly in standard <SPAN
CLASS="ACRONYM"
>SQL</SPAN
> syntax?
Well, you
must understand that indices are implementation-dependent. <SPAN
CLASS="ACRONYM"
>SQL</SPAN
> does not
define the implementation, merely the relations between data in the
database. <SPAN
CLASS="PRODUCTNAME"
>Postgres</SPAN
> does allow non-unique indices, but indices
used to enforce <SPAN
CLASS="ACRONYM"
>SQL</SPAN
> keys are always unique.</P
><P
>Thus, you may query a table by any combination of its columns, despite the
fact that you don't have an index on these columns. The indexes are merely
an implementational aid which each <SPAN
CLASS="ACRONYM"
>RDBMS</SPAN
> offers you, in order to cause
commonly used queries to be done more efficiently. Some <SPAN
CLASS="ACRONYM"
>RDBMS</SPAN
> may give you
additional measures, such as keeping a key stored in main memory. They will
have a special command, for example
<PRE
CLASS="PROGRAMLISTING"
>CREATE MEMSTORE ON <table> COLUMNS <cols></PRE
>
(this is not an existing command, just an example).</P
><P
>In fact, when you create a primary key or a unique combination of fields,
nowhere in the <SPAN
CLASS="ACRONYM"
>SQL</SPAN
> specification does it say that an index is created, nor that
the retrieval of data by the key is going to be more efficient than a
sequential scan!</P
><P
>So, if you want to use a combination of fields which is not unique as a
secondary key, you really don't have to specify anything - just start
retrieving by that combination! However, if you want to make the retrieval
efficient, you'll have to resort to the means your <SPAN
CLASS="ACRONYM"
>RDBMS</SPAN
> provider gives you
- be it an index, my imaginary MEMSTORE command, or an intelligent <SPAN
CLASS="ACRONYM"
>RDBMS</SPAN
>
which creates indices without your knowledge based on the fact that you have
sent it many queries based on a specific combination of keys... (It learns
from experience).</P
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="typeconv2704.html"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="user.html"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="arrays.html"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>UNION Queries</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Arrays</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>
|