Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 10 ■ DATABASE TABLES 413 • SYS_NC_OID$: This is the system-generated object ID of the table. It is a unique RAW(16) column. It has a unique constraint on it, and there is a corresponding unique index created on it as well. • SYS_NC_ROWINFO: This is the same “magic” function we observed with the nested table. If we select that from the table, it returns the entire row as a single column: ops$tkyte@ORA10G> select sys_nc_rowinfo$ from people; SYS_NC_ROWINFO$(NAME, DOB, HOME_ADDRESS(CITY,STREET,STATE,ZIP), WORK_ADDRESS ---------------------------------------------------------------------------- PERSON_TYPE('Tom', '15-MAR-65', ADDRESS_TYPE('Reston', '123 Main Street', 'Va', 45678), ADDRESS_TYPE('Redwood', '1 Oracle Way', 'Ca', 23456)) • NAME, DOB: These are the scalar attributes of our object table. They are stored much as we would expect, as regular columns. • HOME_ADDRESS, WORK_ADDRESS: These are “magic” functions as well. They return the collection of columns they represent as a single object. These consume no real space except to signify NULL or NOT NULL for the entity. • SYS_NCnnnnn$: These are the scalar implementations of our embedded object types. Since the PERSON_TYPE had the ADDRESS_TYPE embedded in it, Oracle needed to make room to store them in the appropriate type of columns. The system-generated names are necessary since a column name must be unique, and there is nothing stopping us from using the same object type more than once as we did here. If the names were not generated, we would have ended up with the ZIP column twice. So, just like with the nested table, there is a lot going on here. A pseudo primary key of 16 bytes was added, there are virtual columns, and an index was created for us. We can change the default behavior with regard to the value of the object identifier assigned to an object, as we’ll see in a moment. First, let’s look at the full verbose SQL that would generate our table for us. Again, this was generated using EXP/IMP since I wanted to easily see the dependent objects, including all of the SQL needed to re-create this object. This was achieved via the following: [tkyte@localhost tkyte]$ exp userid=/ tables=people rows=n Export: Release 10.1.0.3.0 - Production on Sun May 1 14:04:16 2005 Copyright (c) 1982, 2004, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.1.0.3.0 - Production With the Partitioning, OLAP and Data Mining options Export done in WE8ISO8859P1 character set and AL16UTF16 NCHAR character set Note: table data (rows) will not be exported About to export specified tables via Conventional Path ... . . exporting table PEOPLE Export terminated successfully without warnings.
414 CHAPTER 10 ■ DATABASE TABLES [tkyte@localhost tkyte]$ imp userid=/ indexfile=people.sql full=y Import: Release 10.1.0.3.0 - Production on Sun May 1 14:04:33 2005 Copyright (c) 1982, 2004, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.1.0.3.0 - Production With the Partitioning, OLAP and Data Mining options Export file created by EXPORT:V10.01.00 via conventional path import done in WE8ISO8859P1 character set and AL16UTF16 NCHAR character set Import terminated successfully without warnings. Review of the people.sql file that results would show this: CREATE TABLE "OPS$TKYTE"."PEOPLE" OF "PERSON_TYPE" OID 'F610318AC3D8981FE030007F01001464' OIDINDEX (PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE(INITIAL 131072 NEXT 131072 MINEXTENTS 1 MAXEXTENTS 4096 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "USERS") PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 LOGGING STORAGE(INITIAL 131072 NEXT 131072 MINEXTENTS 1 MAXEXTENTS 4096 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "USERS" NOCOMPRESS / ALTER TABLE "OPS$TKYTE"."PEOPLE" MODIFY ("SYS_NC_OID$" DEFAULT SYS_OP_GUID()) / This gives us a little more insight into what is actually taking place here. We see the OIDINDEX clause clearly now, and we see a reference to the SYS_NC_OID$ column. This is the hidden primary key of the table. The function SYS_OP_GUID is the same as the function SYS_GUID. They both return a globally unique identifier that is a 16-byte RAW field. The OID '' syntax is not documented in the Oracle documentation. All this is doing is ensuring that during an EXP and subsequent IMP, the underlying type PERSON_TYPE is in fact the same type. This will prevent an error that would occur if we performed the following steps: 1. Create the PEOPLE table. 2. Export the table. 3. Drop the table and the underlying PERSON_TYPE. 4. Create a new PERSON_TYPE with different attributes. 5.
- Page 407 and 408: 362 CHAPTER 10 ■ DATABASE TABLES
- Page 409 and 410: 364 CHAPTER 10 ■ DATABASE TABLES
- Page 411 and 412: 366 CHAPTER 10 ■ DATABASE TABLES
- Page 413 and 414: 368 CHAPTER 10 ■ DATABASE TABLES
- Page 415 and 416: 370 CHAPTER 10 ■ DATABASE TABLES
- Page 417 and 418: 372 CHAPTER 10 ■ DATABASE TABLES
- Page 419 and 420: 374 CHAPTER 10 ■ DATABASE TABLES
- Page 421 and 422: 376 CHAPTER 10 ■ DATABASE TABLES
- Page 423 and 424: 378 CHAPTER 10 ■ DATABASE TABLES
- Page 425 and 426: 380 CHAPTER 10 ■ DATABASE TABLES
- Page 427 and 428: 382 CHAPTER 10 ■ DATABASE TABLES
- Page 429 and 430: 384 CHAPTER 10 ■ DATABASE TABLES
- Page 431 and 432: 386 CHAPTER 10 ■ DATABASE TABLES
- Page 433 and 434: 388 CHAPTER 10 ■ DATABASE TABLES
- Page 435 and 436: 390 CHAPTER 10 ■ DATABASE TABLES
- Page 437 and 438: 392 CHAPTER 10 ■ DATABASE TABLES
- Page 439 and 440: 394 CHAPTER 10 ■ DATABASE TABLES
- Page 441 and 442: 396 CHAPTER 10 ■ DATABASE TABLES
- Page 443 and 444: 398 CHAPTER 10 ■ DATABASE TABLES
- Page 445 and 446: 400 CHAPTER 10 ■ DATABASE TABLES
- Page 447 and 448: 402 CHAPTER 10 ■ DATABASE TABLES
- Page 449 and 450: 404 CHAPTER 10 ■ DATABASE TABLES
- Page 451 and 452: 406 CHAPTER 10 ■ DATABASE TABLES
- Page 453 and 454: 408 CHAPTER 10 ■ DATABASE TABLES
- Page 455 and 456: 410 CHAPTER 10 ■ DATABASE TABLES
- Page 457: 412 CHAPTER 10 ■ DATABASE TABLES
- Page 461 and 462: 416 CHAPTER 10 ■ DATABASE TABLES
- Page 463 and 464: 418 CHAPTER 10 ■ DATABASE TABLES
- Page 466 and 467: CHAPTER 11 ■ ■ ■ Indexes Inde
- Page 468 and 469: CHAPTER 11 ■ INDEXES 423 value of
- Page 470 and 471: CHAPTER 11 ■ INDEXES 425 One of t
- Page 472 and 473: CHAPTER 11 ■ INDEXES 427 We then
- Page 474 and 475: CHAPTER 11 ■ INDEXES 429 we ended
- Page 476 and 477: CHAPTER 11 ■ INDEXES 431 The data
- Page 478 and 479: CHAPTER 11 ■ INDEXES 433 if ( (++
- Page 480 and 481: CHAPTER 11 ■ INDEXES 435 Table 11
- Page 482 and 483: CHAPTER 11 ■ INDEXES 437 When Sho
- Page 484 and 485: CHAPTER 11 ■ INDEXES 439 an 8KB b
- Page 486 and 487: CHAPTER 11 ■ INDEXES 441 select *
- Page 488 and 489: CHAPTER 11 ■ INDEXES 443 select *
- Page 490 and 491: CHAPTER 11 ■ INDEXES 445 Indicate
- Page 492 and 493: CHAPTER 11 ■ INDEXES 447 an index
- Page 494 and 495: CHAPTER 11 ■ INDEXES 449 Table 11
- Page 496 and 497: CHAPTER 11 ■ INDEXES 451 9 1, 'M'
- Page 498 and 499: CHAPTER 11 ■ INDEXES 453 column w
- Page 500 and 501: CHAPTER 11 ■ INDEXES 455 Bitmap j
- Page 502 and 503: CHAPTER 11 ■ INDEXES 457 INSERT a
- Page 504 and 505: CHAPTER 11 ■ INDEXES 459 7 l_last
- Page 506 and 507: CHAPTER 11 ■ INDEXES 461 ops$tkyt
414<br />
CHAPTER 10 ■ DATABASE TABLES<br />
[tkyte@localhost tkyte]$ imp userid=/ indexfile=people.sql full=y<br />
Import: Release 10.1.0.3.0 - Production on Sun May 1 14:04:33 2005<br />
Copyright (c) 1982, 2004, <strong>Oracle</strong>. All rights reserved.<br />
Connected to: <strong>Oracle</strong> <strong>Database</strong> 10g Enterprise Edition Release 10.1.0.3.0 - Production<br />
With the Partitioning, OLAP <strong>and</strong> Data Mining options<br />
Export file created by EXPORT:V10.01.00 via conventional path<br />
import done in WE8ISO8859P1 character set <strong>and</strong> AL16UTF16 NCHAR character set<br />
Import terminated successfully without warnings.<br />
Review of the people.sql file that results would show this:<br />
CREATE TABLE "OPS$TKYTE"."PEOPLE"<br />
OF "PERSON_TYPE" OID 'F610318AC3D8981FE030007F01001464'<br />
OIDINDEX (PCTFREE 10 INITRANS 2 MAXTRANS 255<br />
STORAGE(INITIAL 131072 NEXT 131072<br />
MINEXTENTS 1 MAXEXTENTS 4096<br />
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1<br />
BUFFER_POOL DEFAULT)<br />
TABLESPACE "USERS")<br />
PCTFREE 10 PCTUSED 40<br />
INITRANS 1 MAXTRANS 255<br />
LOGGING STORAGE(INITIAL 131072 NEXT 131072<br />
MINEXTENTS 1 MAXEXTENTS 4096<br />
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1<br />
BUFFER_POOL DEFAULT) TABLESPACE "USERS" NOCOMPRESS<br />
/<br />
ALTER TABLE "OPS$TKYTE"."PEOPLE" MODIFY<br />
("SYS_NC_OID$" DEFAULT SYS_OP_GUID())<br />
/<br />
This gives us a little more insight into what is actually taking place here. We see the<br />
OIDINDEX clause clearly now, <strong>and</strong> we see a reference to the SYS_NC_OID$ column. This is the hidden<br />
primary key of the table. The function SYS_OP_GUID is the same as the function SYS_GUID.<br />
They both return a globally unique identifier that is a 16-byte RAW field.<br />
The OID '' syntax is not documented in the <strong>Oracle</strong> documentation.<br />
All this is doing is ensuring that during an EXP <strong>and</strong> subsequent IMP, the underlying type<br />
PERSON_TYPE is in fact the same type. This will prevent an error that would occur if we performed<br />
the following steps:<br />
1. Create the PEOPLE table.<br />
2. Export the table.<br />
3. Drop the table <strong>and</strong> the underlying PERSON_TYPE.<br />
4. Create a new PERSON_TYPE with different attributes.<br />
5.