|
![]() |
![]() |
![]() |
![]() |
![]() |
How LOBs are Stored in the Oracle8 DatabaseThe four LOB data type columns are BLOB, CLOB, NCLOB, and BFILE. A BLOB column stores binary objects, such as graphics, video clips, or sound files, while a CLOB column stores single-byte fixed-width character objects, such as text documents. The NCLOB column type is the same as the CLOB column type, but for multibyte character sets. Because these three types of LOB can be stored inside the database, they are referred to as "internal" LOBs. The fourth type of LOB, BFILE, is a binary file that is always stored outside the database, and is referred to as an external data type.Internal LOBsThe internal LOBS -- BLOB, CLOB, and NCLOB -- automatically gain the benefits inherent in the Oracle database. Using internal LOB data type columns for your multi-media solution can help reduce administration and management costs. For example, with unstructured information stored directly in the Oracle8 database, you won't have to synchronize the unstructured information with the structured relational data. Moreover, because the unstructured data is stored by the database, your application will seamlessly take advantage of features such as backup and restore. In addition, LOB data will also maintain the ACID (atomicity, concurrency, integrity, and durability) properties required by transactional systems, which means that changes to an internal LOB can be committed or rolled-back.In all cases, Oracle8 stores a locator in-line with the data row for a LOB. The locator is a pointer to the actual location of the LOB value or data. Although BLOB, CLOB, and NCLOB data types are internal to the database, that doesn't mean that the data is always physically stored within the same table space as the column. For example, within a given table containing a BLOB column, the Oracle8 database locator values point to a separate location that the database creates to hold the LOB data, which can be a table space separate from the table containing the BLOB column. Storing the data out-of-line in this manner can provide for a more robust solution: The database won't have to scan the LOB data each time it reads multiple rows from the database because only the LOB's locator values will be read -- the actual LOB data is only read when its required. LOBs can also be stored in-line -- within a row of the same table in which the other data columns are stored -- if it is less then 4k. If the LOB data will be larger than 4k, (up to 4 gigabytes), it can be stored in a separate tablespace. External LOBsUnlike the BLOB, CLOB, or NCLOB data columns, a BFILE data column can never be stored in-line in a table; rather, the data is stored on CD-ROM, PhotoCD, or directly in the file system of an operating system. When you define a BFILE data column an Oracle8 database table, only a locator for the binary data is stored in the table.What's the advantage of a BFILE implementation? Your application may have multiple rows of a table or different tables pointing to the same binary file located in the operating system. If an application contains many rows that point to the same digital images, storing data as BFILE can save a lot of disk space. What this all boils down to is that you must plan for the type of large objects you'll be storing: How big will they be? How many tables will access them? How frequently will they need to be updated? First decide whether to store your LOB data in-line or out-of-line (in a separate table), and then decide whether your needs are best served by the internal LOBs or by the external LOB data type, a BFILE. Although BFILE data won't get backed up with the Oracle8 database and it can't participate in transactions (and therefore it doesn't maintain ACID properties with relational data, as do the internal LOB data types), the BFILE data type is appropriate for relatively static data, such as the digital photographs of employees stored on a PhotoCD. The example application in Listing 1 uses the BFILE data type for employee photographs. I used the default EMP table that ships with Oracle8 and added a BFILE column to the table using the following statement:
alter table emp add(photo bfile); Because BFILE content is always located external to the database, some additional preliminary setup is required before you can use this type of LOB data column. Specifically, before loading a column of BFILE data type you must create a directory object in the database -- a logical name within the database that maps to a file-system path. (This is not necessary for the internal LOB data types, for obvious reasons.) The Oracle8 SQL command CREATE DIRECTORY is used to create this logical alias name and object, as shown in the following statement which creates a directory object called IMGDEMODIR in the Oracle database that functions as an alias for the c:\orant\ord80\img\demo sub-directory on the Windows NT Server system: connect system grant CREATE ANY DIRECTORY to scott / connect scott create or replace directory "IMGDEMODIR" as 'c:\orant\ord80\img\demo'; All the images for the application will be placed directly in this directory. You can create directory objects to the sub-directory from many other databases and incorporate the content in multiple applications, and yet have only the single directory of unstructured data. Loading LOBsThe PL/SQL stored procedure shown in (Listing 2) uses the SQL INSERT command to insert information about an employee in the EMP table. The information includes employee name, salary, commission, hire date, department, and photo. As you can see in the listing, the BFILENAME() function inserts the photo; the BFILENAME() function takes the directory object and the filename that exists in the directory as its arguments. The image file must exist in the directory before the function can be executed. The procedure in Listing 2 also displays the size of the new photo using the DBMS_LOB package. At this point, a new employee row is inserted with a locator that points to the image stored in the operating system file. You can also insert information for other LOB types by writing similar PL/SQL blocks or procedures.Accessing LOBsWhen you use the SQL SELECT command on a LOB column, you don't get the actual LOB data; rather, you get the locator for the LOB. This locator can then be used with the DBMS_LOB package or OCI to read or write the LOB to the database. The procedures DBMS_LOB.READ() and DBMS_LOB.WRITE() can be used to read or write LOB information using a locator.To call a stored procedure from JDBC you need to create an OracleCallableStatement object instead of a Statement object. When you call database stored procedures, you need to map database-stored-procedure parameter data types to JDBC data types. For example, the NUMBER data type can be mapped to JDBC's LONG data type. Similarly, the Oracle8 BFILE data type can be mapped to the Oracle extended JDBC data type of VARBINARY. (Consult the Oracle JDBC documentation, available at Oracle Technology Network (http://technet.oracle.com), for complete information about data-type mappings.) You can pass parameters of different data types to a stored procedure by calling different methods of the OracleCallableStatement class, as shown in this excerpt from the Java source code:
long amount_read = 0;The excerpt from the sample Java program provides an example of calling the DBMS_LOB.READ() stored procedure from JDBC, using Oracle syntax. The Oracle JDBC drivers also support the SQL-92 syntax. The procedure expects four parameters as input, including the number of bytes you want to retrieve (size of chunk). It returns the size of binary information in the second parameter and binary data (from the BFILE column) in the fourth parameter from the database. The setLong method of the OracleCallableStatement is used for passing the second and third parameters, since the procedure expects the NUMERIC data type of the Oracle8 database. To receive data from the stored procedure you need to use the registerOutParameter() method. When you call the registerOutParameter method, you need to specify the position in the stored procedure's parameter list and the type of data that will be returned from the procedure. The data type of parameter that you specify with this method is the JDBC data type mapped for the data type of the stored procedure parameter. You also must map between other Oracle8 data type and JDBC drivers and use different methods of the OracleCallableStatement class, depending on these data types. The listing above also shows other methods, such as getLong() of OracleCallableStatement, being used to assign values returned by stored procedures to Java variables. After retrieving the information from the database, you need to display it. The sample application in Listing 1 shows how to read digital images stored in BFILE data columns and display it. The displayResult() method in Listing 1 displays all the information retrieved from the Oracle8 database. Applications developed using Java and JDBC can then be deployed on the Oracle Application Server, or directly in the database (with Oracle8i). ConclusionIn this article, you've learned how to enrich your applications by integrating multimedia data types as LOBs in an Oracle8 database. You've also learned about storing and accessing them using Java and JDBC, and accessing PL/SQL stored procedures from Java.This approach, of course, is not the only way to incorporate unstructured data. For example, an alternative to using LOBs in the Oracle database is integrating the optional Oracle8 Image Data Cartridge, which can scale and crop images, and interchange image formats. Furthermore, Java applications can also access relational and nonrelational data using SQLJ rather than coding JDBC directly; SQLJ is an industry standard interface being developed by Oracle, IBM, Tandem, and many others in the industry. SQLJ is easier to use and involves far less writing of code; when the code is compiled, the SQLJ translator replaces the embedded SQLJ statements with JDBC statements. In future articles, we'll cover both topics -- implementing the Image Data Cartridge and using SQLJ for your Java database programming -- but having a handle on JDBC, Java, and LOBs will give you a greater understanding of these other technologies. Related LinksOracle8 Document ArchiveOracle8: The Complete Reference
Samir Shah (ssshah@us.oracle.com) is an
Oracle Certified Professional and a technical team lead for Oracle Corporation.
|