First it was my parents, then my high-school counselor, my college professors, my business coach, and the list goes on; but they all essentially told me that same thing: In order to be successful, you need to have a plan. When it comes to successful database deployment, the same is true—you need to plan. Although you may cringe at the idea of having to take the time to create a plan, remember that it can end up saving you a lot of time later on.
So this first part of this tutorial covers the idea of planning. While planning, some of the questions you need to ask yourself include:
- What capabilities do I need in the database software?
- What type of applications am I expecting to connect?
- How many users are there, and where are those users connecting from?
- What type of data and how much data am I going to store?
- What is the expected response time from my application?
- Am I going to use existing hardware or buy new?
- Is one person going to maintain everything surrounding the data, or am I going to split out roles to a team?
The questions could go on, but let's stop there for now. The intent of this section is not to go in depth about all these questions but to get you thinking about them and discuss some high-level points about some of them.
Informix Dynamic Server comes in four different editions:
The Developer Edition of IDS is a free product meant for application development and testing only. It contains most of the functionality of the Workgroup Edition but has no IBM technical support capabilities. It also has scalability limits for processors, memory, and storage.
The Express Edition is meant for small- to medium-sized businesses and is limited to running on Linux and Windows operating systems. It also contains most of the functionality of the Workgroup Edition with scalability limits.
The Workgroup Edition is meant for medium-sized companies or departmental servers of an enterprise. It is available on various Unix/Linux operating systems, as well as Windows and Mac OS X. Workgroup Edition adds additional functionality, such as limited Enterprise Replication (ER) and High-Availability Data Replication (HDR). The Workgroup Edition also has limits on scalability.
The Enterprise Edition contains all the functionality of Workgroup Edition with unlimited scalability. Enterprise includes full HDR and ER functionality, as well as additional functionality for the Continuous Availability Feature, Storage Optimization, LBAC, and more.
One of the first pieces of planning is deciding which edition of IDS is needed to support your business requirements.
The applications that connect to a database are usually split into two categories:
- Online Transaction Processing, better known as OLTP
- Decision Support Systems, better known as DSS, but sometimes also called data warehousing
"So what's the difference?" you ask. Let's look at an example.
OLTP-type processing is like a call center application. When you call in to your credit card company (or help desk of any sort), the representative on the line usually asks you for something that is unique to your account, like an account number. That account number is used to search in the database to get a few records associated with only you. It could be just one record—maybe your account information; or it could be a couple dozen, like your account information plus the last 15 transactions on your account. Either way, it is designed to be a quick search that brings back the data in a matter of a couple seconds or less. Although it could bring back a couple dozen rows with data from several tables, the rows that it brings back are just a fraction of a fraction of the number of rows that are kept in the database. The 20 rows that the application may have brought back is therefore nothing compared to the 200 million rows in the table. This is not to make you feel small in the grand scheme of things; I'm only trying to point out a couple of key elements to an OLTP-type system. It:
- Returns a few rows from a query
- Has a very quick response time—usually a couple seconds or less
- Uses uniqueness and indices to get row set
- Is a read and write type environment
- Allows a lot of users
OLTP systems are designed to be read and write systems. User applications, like the credit card help desk, will not only select data from the database, but will also frequently update and insert new data.
DSS-type queries, for lack of a better term, are reporting-type queries. They are longer-running-, farther-reaching- (through the data) type queries. Taking the credit card company example from above, the CEO of the company wants to:
- Find out how many credit card transactions went through last month
- Have a report of all those customers that are delinquent on their accounts
Notice that these queries are not associated with one particular customer. The first query may use only one table to get its data (or it could use several), but it is having to do a much larger search over a span of data to get its results for the one month, and then aggregate (count) the data to get the final result. The second query is similar to the first, but brings back more data.
Many people think of DSS-type queries as queries that return a book of data. However, that is not at all true. Of the examples, the first query is a DSS query, but it only returns one row—one value, in fact—the count. The second query could return a book of data, depending on how many people are delinquent on their accounts.
The key elements associated with a DSS query are:
- Longer running queries; can be minutes to hours
- More resource intensive
- Accumulate more rows that match the criteria of the query
- Larger aggregation of the data (sum, min, max, count, and so on)
- Uses sequential scan on the table since larger data sets are involved.
DSS environments are more read-only-type environments. Although the data has to get into the system somehow, it is usually with bulk loads and then once if the system does not get updated or is updated very infrequently.
So don't categorize a query by the amount of data that it brings back, but instead by the key elements of the query itself.
The Data Model that is used during the design of the database is also very important. IDS can take advantage of three data models:
- Relational data model - A typical OLTP-type model
- Object-relational data model – Adds to the relational data model by using the extensibility options of IDS (extended data types, user-defined Routines, user-defined types, user-defined aggregates, and so on)
- Dimensional data model - typical DSS data model, supporting online analytical processing (OLAP)
Although in today's environments, a single database doesn't necessarily have the luxury of being just OLTP or DSS, it is always a good idea to try and figure out what the main application type for your database will be, and follow a design path that matches that type.
In order to accommodate the fact that many databases have both types of applications connecting to them at the same time, IDS has configurable parameters to help performance of both OLTP and DSS queries running on the same database.
Another piece of planning is taking care of user requirements.
The basic questions to ask are:
- Do I need any special users or groups for the software?
- Where are the users connecting from?
- How many users do I expect to be connecting simultaneously?
The importance of answering these three questions is not only good for the planning of the database, but also for the planning of the hardware requirements.
IDS on Unix/Linux requires an "informix" user account as well as an "informix" group set up on the installation machine. Windows loosens that requirement and allows for either an "informix" user or the use of a local system user and an "Informix-Admin" group. During installation on Windows, you can choose which user account you would like to use.
By default, the user "informix" is considered the "super-user" of the IDS software. It has access to everything and can do anything that needs to be done with the IDS software.
IDS 11.50 uses external user authentication, which just means that it doesn't have users set up inside the software, but relies on other software to help it authenticate a user. This external software can be the operating system (OS) authentication mechanism of the machine where IDS is running, LDAP, MS Active Directory, or a Pluggable Authentication Module (PAM).
Note: Whichever way you decide authentication, the important thing to remember is that ALL users that need access to the database have to have an account and password with an external authentication mechanism so the database can authenticate them and allow them access to the data. This can take some major planning depending on whether you have two user accounts connecting or 2000 user accounts connecting.
As mentioned previously, by default, the "informix" user is the "super-user" of the IDS installation. However, certain specifications require the administrative power to be split out under multiple users, with each user having a subset of the total administration. This is known as role separation. Role separation is meant to be a kind of checks-and-balances mechanism. IDS role separation splits this out under two categories:
- Administrative tasks for people who run the instance
- Audit tasks for people who audit what is happening on the instance
Role separation must be turned on during the installation of the
software by either setting the
environment variable before starting the installation process, or by
actively turning it on during the interactive installation process.
Role separation can only be turned back off by
uninstalling/reinstalling the IDS software. Role separation uses user
accounts on Windows and group accounts on Unix/Linux. If role
separation has been turned on, the installation process will ask for
the information needed for these user and group accounts.
The three users who take part in role separation are:
- Database System Administrator (DBSA) - controls general operations of the instance
- Database System Security Office (DBSSO) - determines what to audit
- Audit Analysis Officer (AAO) - monitors the audit trail
Other users that aren't part of role separation but might need some planning for include:
- Database Administrator (DBA) - manages a database on the instance
- Operating-System Administrator (OSA) - satisfies OS requirements
- System Users - any user that needs to get to the data
Part of database planning is being familiar with what data types are available for use to store the data. The easiest way to describe how data is stored in a database is by using a spreadsheet analogy. By now, you hopefully have used or seen some type of spreadsheet program (for example, Microsoft® Excel®). When you look at the spreadsheet, it is organized in rows and columns of cells. When you look at a column of cells (vertical data), usually all data in the same column is alike—a column of dates, or a column of money values—with a column header that describes what the data means.
When you look at a row of cells (horizontal data), all the data in the cells together describes one particular instance of what the spreadsheet is representing. In the example below (Table 1), this spreadsheet describes customers of the XYZ Shoe Store. Each row describes info about one particular customer, where each column describes one concept being kept about all the customers. So for each customer, you are storing his name, age, shoe size, the last time he bought shoes from the store, and how much he bought during that transaction.
Table 1. Data for examples
|Name||Age||Shoesize||Last Trans Date||Last Trans Amt|
Databases don't keep data in spreadsheets, but instead in tables. Tables, just like spreadsheets, are made up of rows and columns. During definition of the table you specify what columns of data are being held and what data type each column uses. A data type constrains the type of data the column can hold. If you define a column to be of an integer data type, then that column cannot contain letters; it is constrained to only containing whole numbers. The rows of the table are added as your applications start storing data in the columns of the table. Data is stored one row at a time. The example in Table 1 above has five columns—the first column, Name, is of character/string data type; Age is of integer data type; Shoesize is of decimal data type; LastTransDate is of date data type; and LastTransAmt is of money data type.
Now that you have an idea of where data types are used, let's take a look at the data types that are available in IDS.
- Built-in data types
- BIGINT - whole numbers from -(263-1) to 263-1
- BIGSERIAL - whole numbers from -(263-1) to 263-1, automatically incremented by the server; sometimes used as a surrogate primary key
- BLOB - Binary Large Object up to 4TB in size, storing objects in their native format
- BOOLEAN - 't' or 'f' value; can be tested in expressions
- BYTE - older version of BLOB with 231 byte theoretical size limit and a practical limit determined by your disk capacity
- CHAR(n) - stores 'n' characters of data; if value is greater than n, blank padded up to size 'n'
- CHARACTERVARYING(m,r) - ANSI-compliant VARCHAR
- CLOB - Character Large Object up to 4TB in size; stores character data
- DATE - the calendar date; default format MM/DD/YYYY; can
be changed with
DBDATEenvironment variable; specifies a point in time.
- DATETIME - the calendar date and time; default format
YYYY-MM-DD HH:MM:SS.FFF; can be changed with
DBTIMEenvironment variable; specifies a point in time.
- DECIMAL(p,s) - decimal values, where 'p' is the total number of digits and 's' is the number of digits to the right of the decimal point
- NUMERIC(p,s) - same as DECIMAL
- DOUBLE PRECISION - same as FLOAT
- FLOAT - double-precision floating-point number with up to 17 significant digits
- IDSSECURITYLABEL - a VARCHAR(128) used only with Label Based Access Control (LBAC)
- INTEGER - whole numbers from -(231 -1) to 231 -1
- INT8 - whole numbers from –(263 -1) to 263 -1
- INTERVAL - format same as DATETIME, but specifies a span of time
- LVARCHAR(m) - long variable character length field with 'm' as max size; only use as much space as needed to store data up to 'm' size; max size 2GB when used with UDT, otherwise max 32K
- MONEY(p,s) - just like DECIMAL value, except formatted
with money characters; default is $ and ., but can be
- NCHAR(n) - stores fixed length character data, but includes the use of Global Language Support (GLS) to store both single-byte and multi-byte character sets that are supported by the database locale; also allows for the use of localized collation sequences
- NVARCHAR(m,r) - same as VARCHAR, but with special characteristics like NCHAR
- REAL - same as SMALLFLOAT
- SMALLFLOAT - single-precision floating point numbers with approximately nine significant digits
- SERIAL - whole numbers –(231 -1) to 231-1, automatically incremented by server; sometimes used as primary key
- SERIAL8 - same as SERIAL with a range of –(263 -1) to 263-1
- SMALLINT - whole numbers from -32767 to 32767
- TEXT - older version of CLOB with maximum size of 2GB
- VARCHAR(m,r) - variable character length field with 'm' as the maximum size (up to 255) and 'r' as the smallest reserved space; if value being stored is less than 'r', the value will be space padded up to size 'r'; if value being stored is greater than 'r' and less than 'm', then it will only use as much space as needed to store the value
- Extended data types
- Complex data type
- User-defined data types
- Distinct types
- Opaque types
The built-in data types are considered atomic, which means that they can't be broken into smaller pieces. Each built-in data type has its own characteristics that make it unique.
Listing 1 provides an example of using built-in types when creating the customer table (data from Table 1):
Listing 1. Using built-in types
CREATE TABLE customer ( Name CHAR(55), Age INTEGER, Shoesize DECIMAL(3,1), LastTransDate DATE, LastTransAmt MONEY(5,2) );
Since the built-in data types cannot encompass every possible type of data that users want to store, IDS has the capability to extend them by combining the built-ins together or by adding new user-defined data types. The complex data type category is made up of two data types known as row and collection.
The best way to describe a ROW data type is that it mimics a row in a table, but you put that whole row into a single column. So it is a multi-part data type made up of the built-in data types. It is no longer atomic. Row data types can be named or unnamed.
Using the XYZ Shoe Store example from above, maybe you want to store the full name of the customer—first, middle, and last. Instead of creating three different columns—one for each part—you can create a single column that has three parts.
The COLLECTION data type is actually a category of three underlying data types called set, multiset, and list. The collection data type allows groups of data, all of the same data type, to be stored together in a single column.
Using the XYZ Shoe Store example from above, maybe you want to store the customers' favorite brands of shoes. You don't want to create multiple columns because you because you might not know how many columns you would need. Some people have only one favorite brand; other people have five favorite brands when it comes to shoes. Since all brand names are just character strings, they are all of the same data type. So you can create a column called FavBrands of SET type that stores character string data. Now that single column can store as many brands as that customer has favorites. With SQL, you can then go in and select all of the customers whose FavBrands include Nike regardless of how many favorite brands are listed. You would select a SET type since SET doesn't allow duplicates in the collection. It wouldn't make sense to have a value of 'Nike','Keds','Nike'. Both multi-set and list allow duplicates. Collections do not allow Null elements, so when defining a collection the NOT NULL constraint must be specified.
Listing 2 provides an example for creating the customer table using the
above ROW and COLLECTION ideas:
Listing 2. Using ROW and COLLECTION
CREATE TABLE customer ( Name ROW( fname CHAR(15), mi CHAR(1), lname CHAR(35)), Age INTEGER, Shoesize DECIMAL(3,1), LastTransDate DATE, LastTransAmt MONEY(5,2) FavBrands SET(CHAR(10) NOT NULL) );
After making the changes my table data would look something like:
Table 2. Data being used for examples
|Name||Age||Shoesize||Last Trans Date||Last Trans Amt||FavBrands|
Although the built-in types and complex types can cover much of the data that a user would want to store, it is possible that new data types will be needed. New applications and technologies bring new things that could need new data types. So, instead of IDS deciding when a good time to add a new data type is, IDS has empowered you with the capability to add new data types whenever you need them. These data types are known as user-defined types, or UDTs. You design it, you tell IDS how to interact with it, and there you go—you have great new functionality.
If only everything in life were that easy, including this, then we could all be doing it. Actually, it isn't necessarily hard; there are just several things that you have to do to make it all work. More of this will come up as this tutorial continues to discuss UDTs and support functions for UDTs. So back to UDTs….
As seen in the available data types list above, the first type of UDTs you have is called a distinct type. To put it simply, a distinct type is just the renaming of a built-in data type. It inherits the basic characteristics of the built-in type, but not the support functions.
Example: Create distinct type Shoesize as DECIMAL(3,1):
Since Shoesize is being defined as a decimal, it will take on the storage characteristics of the decimal type. However, not everything you can do with a decimal value makes sense to do with a Shoesize value. An example would be addition. It doesn't make sense to add two shoesizes together to make another shoesize. The addition function (+) is considered a support function in IDS. Since IDS doesn't know whether the support functions will make sense to the newly defined distinct type, it just automatically disables all support functions on the distinct type. Because of this, you also can't compare a shoesize value to a decimal value. Comparing values is also considered part of support functionality. Even though shoesize is defined as a decimal, they are considered two different (distinct) types that can't be compared. If you want to compare a decimal value to a shoesize value you have to first cast one of them to be of the same type as the other, and then the comparison can be made.
So you ask, "If no support functions are supported on this new 'distinct' data type, what good does it do me?" Well, you might have something special you can do with shoesizes, like telling if one is larger than another one. This is kind of a bad example, since shoe sizing follows a normal incremental value just like decimal values do. However, say that you made this to incorporate XS, S, M, L, XL, and XXL values as well. You would have to change shoesize from a decimal to a character type. But now if you wanted to see if a customer's shoe size had grown or shrunk since he last bought a pair of shoes, you could no longer rely on normal ordering (alphabetical in this case). If you tried to rely on alphabetical ordering, then the shoe sizing chart would look like L, M, S, XL, XS, XXL. But that isn't the case because you know that XS is the smallest in the shoe sizing list. Since you couldn't rely on IDS's built-in functions to help with this, you need an alternative. IDS's alternative is to allow the writing of external routines that can then be called in normal SQL. So you could write a routine to do the shoe sizing comparison for you. These new routines are known as user-defined routines (UDRs). This tutorial covers UDRs a little later on.
The other kind of UDT is known as an OPAQUE data type. Just like the name describes, an opaque type is a new type that IDS doesn't understand at all. Not only does the data type have to be described to IDS, something like a C structure, but you also have to tell IDS how the structure should look like on disk, how to convert it between disk format and display format, how to index it, and any support functions you want to use for it. People always ask, "If I have to do so much work, why should I use IDS when I can just write my own application?" Although OPAQUE data types can take a lot of work to set up, they can have high reward because you automatically have access to all the rest of the database capabilities. Once you define the support functions, IDS can use those anywhere in normal SQL statements, making it look just like any built-in type. So now you have transactional integrity, backup and restore, storage, user functionality, integration with other data types, and everything else that is already built into the Relational Database Management System (RDBMS).
A prime example of using OPAQUE types is the GeoSpatial Datablade that defines a GeoPoint data type, which stores four-dimensional geographic coordinates. The support functions around this help analyze distance, proximity, intersection, and other functions based on geographic points. These functions can be included inside of normal SQL statements so that character data, geopoint data, and any other data type data can come out in the same result set.
The support functions for any UDT can be written in C, Java, or Stored Procedure Language (SPL). In fact, it doesn't just stop with UDTs. A DBA can create a UDR to support built-in data types as well.
The average (AVG) aggregation function (routine) for built-in numeric data types completely ignores NULL values when it is doing its calculations. So, maybe for your analysis you need an AVG routine that can take NULL values and convert them to zeros and include them in the calculation. You can write a UDR that overloads the built-in AVG function and use your new routine for built-in data types, UDTs, or both.
Notice in the example, the terms function and routine are synonymous.
This is because the term routine is just a category that encompasses
two actual elements: functions and procedures. So when you create a
routine you actually use either the
CREATE FUNCTION or
"Why the two?" you ask. By ANSI standards definition, a function can both take and return values, where a procedure can take values but shouldn't return anything. An example of a function would be the SUM function—you pass it 2 and 2, and it returns 4. An example of a procedure would be updating a person's salary—you pass it the new salary but it doesn't need to return anything back to the user. As of 11.50, IDS is not completely ANSI-compliant because it still allows return values from procedures. This is done for backwards compatibility. Just make sure you keep the ANSI standards in mind when writing any future routines.
Before leaving the extensibility topic of UDTs and UDRs, let's look at one more concept known as a datablade. Since we have discussed what UDTs and UDRs are, the Datablade concept should be an easy one. A datablade is the packaging together of UDTs and UDRs for a specific reason. The reason is usually because they have something in common, like a given functionality. An example would be the Geodetic Datablade. Inside the Geodetic Datablade are all the UDTs and UDRs needed to do geospatial storage, retrieval, indexing, and all kinds of analysis.
Let's pretend for a second that you need a new printer for your computer. You head to the local computer peripheral store, pick one out you like, and take it home with you. When you get home, you open the box, and the first thing you do is pull out the User Manual, read it cover to cover, and then unpack the rest. Right? If you are like the other 99% of us, you may pull out the manual, but you set it aside because you are too excited about getting your printer hooked up. Well, peripheral manufacturers figured that out, and to help out, they put something else in the very top of the box—a thing they call a "Read Me First" paper with the 10 or 20 easy steps to getting the printer working.
IDS has incorporated this same idea in two parts. The first is a README.html file that is in the top directory when you extract the software from the installation media. The README file has very basic installation instructions as well as links to several other documentation files known as "release notes". (This tutorial discusses more about installation in the "Installation" section.) The release notes describe new features, supported releases, kernel parameter values, deprecated features, and information about known problems and their workarounds. If you are upgrading from one release of IDS to another, the release notes are a great place to learn about changes made between releases. If you are installing brand new, they are still a great place to find out information about this version and other locations for information. If you are inheriting an already installed product, the release notes can still be found in a sub-directory of the directory where IDS is installed. Let's call the directory where IDS is installed INFORMIXDIR. So the release notes would be found in /INFORMIXDIR/release on Unix/Linux or C:\INFORMIXDIR\release on Windows. Actually, they would be found in a localized set of directories under that. These localized directories follow a Global Language Support (GLS) convention. If you are installing the US English version of the product on Unix/Linux, the total directory structure will look like: /INFORMIXDIR/release/en_us/0333.
Depending on your country and language, the last two sub-directories could be named differently but will still have a similar structure. Inside that final directory you will find release notes, in both html and text format, for all the IBM Informix products installed on this machine.
The last part of the release notes section started bringing in the idea of Global Language Support (GLS). Not all countries of the world speak the same language, have the same alphabet, or use the same money. So you shouldn't expect the software to only be in one language either. That is where localization comes in. "Localization" is the process of transforming a product to meet a specific cultural environment. As part of localization, you create culture-specific resource files, translation files for messages and errors, translation files for the product user interface, and set the date, time, and money formats.
Defining a locale takes it one step further; it uses the localized
files, but also specifies a code set (character mapping) and collation
sequence (dictionary sort order). This separation allows multiple
locales to exist for the same localization, similar to a country that
has multiple regions. All regions speak the same language, but each
region has their own slight variation to it. The product and hardware
type will determine the default locale that is used when creating a
database. This is known as the DB_LOCALE. For IDS product bought in
the U.S. and installed on Unix/Linux, the default DB_LOCALE is
en_us.8859-1 (also known as en_us.819). If installed on Windows, the
default DB_LOCALE is en_us.1252. If you want to change the DB_LOCALE
from the default, it has to be specified at database creation time by
DB_LOCALE environment variable
in the session that runs the
CREATE DATABASE SQL statement.
ISO 8859-1 character encoding is for the Latin alphabet, which many countries share.
Although the DB_LOCALE specifies the default localization for the database, clients that connect to the database have the capability to use a different localization. Clients have the CLIENT_LOCALE environment variable that specifies the locale of the client. In order for the database and client to exchange information, their locales have to either be the same or compatible (convertible).
When storing character data for GLS, it is important to use the NCHAR
and NVARCHAR data types, instead of the CHAR and VARCHAR data types.
The "N" data types allow the collation (sort order) of data based upon
the CLIENT_LOCALE, instead of just on the DB_LOCALE. The
SET COLLATION SQL statement allows for a
client to change this dynamically inside their current session.
Listing 3 shows the formatting concepts of GLS
locales. Since a lot of countries use the Latin alphabet, many of the
code sets for these countries are compatible. After creating th Shoe
store table from above (see Table 1) and
populating it with one row, I ran the following
SELECT SQL statement multiple times, but
variable to something different but still compatible with the
DB_LOCALE for each run.
Listing 3. GLS locals
SELECT name.fname, SUBSTR(TO_CHAR(lasttransdate,"%B %d %Y"),1,15), lasttransamt FROM customer; $ export CLIENT_LOCALE=en_us.8859-1 --(setting for US English) fname (expression) lasttransamt Fred March 21 2009 $85.43 $ export CLIENT_LOCALE=nl_nl.8859-1 --(setting for Dutch Netherlands) fname (expression) lasttransamt Fred maart 21 2009 F 85,43 $ export CLIENT_LOCALE=de_de.ASCII --(setting for Germany German) fname (expression) lasttransamt Fred Mrz 21 2009 85,43DM $ export CLIENT_LOCALE=pt_br.8859-1 --(setting for Brazil Portuguese) fname (expression) lasttransamt Fred Março 21 2009 (85,43)R$
Notice how by just changing the CLIENT_LOCALE, the data format comes
out differently. (the format, not the data). You have to be careful
when you use this because a date is a date in any country, but $85 US
is not equal to 85 Brazilian Reals. Additionally, the reason why all
the dates came out in Month Day Year format is because of the call to
TO_CHAR function with the formatting
set to %B %d %Y.
Listing 4 shows the output if you remove the
call to the
TO_CHAR function and rerun the
SQL statement with the given CLIENT_LOCALE:
Listing 4. Output
$ export CLIENT_LOCALE=pt_br.8859-1 fname (expression) lasttransamt Fred 21/03/09 (85,43)R$
To recap, GLS libraries allow an application to meet cultural expectations of the data without having to change the application. GLS locales, through the use of special data types, environment variables, and SQL statements, allow for the dynamic formatting and sorting of data to meet the clients standards. All of this can be done without having to write the client application differently for every country/region of the world that it might be used in.
In the first part of this tutorial, you have learned about:
- The two different types of applications used against RDBMS systems
- How user authentication is treated in IDS
- All the different data types that IDS has available to use
- IDS extensibility through UDTs and UDRs
- IDS "Read-me first" files and release notes
- GLS localization
If you want more information on planning for a database, take a look through the "Installing IDS" topic in the IBM Informix Dynamic Server 11.50 Information Center (see Resources).