- •Using Your Sybex Electronic Book
- •Acknowledgments
- •Contents at a Glance
- •Introduction
- •Who Should Read This Book?
- •How About the Advanced Topics?
- •The Structure of the Book
- •How to Reach the Author
- •The Integrated Development Environment
- •The Start Page
- •Project Types
- •Your First VB Application
- •Making the Application More Robust
- •Making the Application More User-Friendly
- •The IDE Components
- •The IDE Menu
- •The Toolbox Window
- •The Solution Explorer
- •The Properties Window
- •The Output Window
- •The Command Window
- •The Task List Window
- •Environment Options
- •A Few Common Properties
- •A Few Common Events
- •A Few Common Methods
- •Building a Console Application
- •Summary
- •Building a Loan Calculator
- •How the Loan Application Works
- •Designing the User Interface
- •Programming the Loan Application
- •Validating the Data
- •Building a Math Calculator
- •Designing the User Interface
- •Programming the MathCalculator App
- •Adding More Features
- •Exception Handling
- •Taking the LoanCalculator to the Web
- •Working with Multiple Forms
- •Working with Multiple Projects
- •Executable Files
- •Distributing an Application
- •VB.NET at Work: Creating a Windows Installer
- •Finishing the Windows Installer
- •Running the Windows Installer
- •Verifying the Installation
- •Summary
- •Variables
- •Declaring Variables
- •Types of Variables
- •Converting Variable Types
- •User-Defined Data Types
- •Examining Variable Types
- •Why Declare Variables?
- •A Variable’s Scope
- •The Lifetime of a Variable
- •Constants
- •Arrays
- •Declaring Arrays
- •Initializing Arrays
- •Array Limits
- •Multidimensional Arrays
- •Dynamic Arrays
- •Arrays of Arrays
- •Variables as Objects
- •So, What’s an Object?
- •Formatting Numbers
- •Formatting Dates
- •Flow-Control Statements
- •Test Structures
- •Loop Structures
- •Nested Control Structures
- •The Exit Statement
- •Summary
- •Modular Coding
- •Subroutines
- •Functions
- •Arguments
- •Argument-Passing Mechanisms
- •Event-Handler Arguments
- •Passing an Unknown Number of Arguments
- •Named Arguments
- •More Types of Function Return Values
- •Overloading Functions
- •Summary
- •The Appearance of Forms
- •Properties of the Form Control
- •Placing Controls on Forms
- •Setting the TabOrder
- •VB.NET at Work: The Contacts Project
- •Anchoring and Docking
- •Loading and Showing Forms
- •The Startup Form
- •Controlling One Form from within Another
- •Forms vs. Dialog Boxes
- •VB.NET at Work: The MultipleForms Project
- •Designing Menus
- •The Menu Editor
- •Manipulating Menus at Runtime
- •Building Dynamic Forms at Runtime
- •The Form.Controls Collection
- •VB.NET at Work: The DynamicForm Project
- •Creating Event Handlers at Runtime
- •Summary
- •The TextBox Control
- •Basic Properties
- •Text-Manipulation Properties
- •Text-Selection Properties
- •Text-Selection Methods
- •Undoing Edits
- •VB.NET at Work: The TextPad Project
- •Capturing Keystrokes
- •The ListBox, CheckedListBox, and ComboBox Controls
- •Basic Properties
- •The Items Collection
- •VB.NET at Work: The ListDemo Project
- •Searching
- •The ComboBox Control
- •The ScrollBar and TrackBar Controls
- •The ScrollBar Control
- •The TrackBar Control
- •Summary
- •The Common Dialog Controls
- •Using the Common Dialog Controls
- •The Color Dialog Box
- •The Font Dialog Box
- •The Open and Save As Dialog Boxes
- •The Print Dialog Box
- •The RichTextBox Control
- •The RTF Language
- •Methods
- •Advanced Editing Features
- •Cutting and Pasting
- •Searching in a RichTextBox Control
- •Formatting URLs
- •VB.NET at Work: The RTFPad Project
- •Summary
- •What Is a Class?
- •Building the Minimal Class
- •Adding Code to the Minimal Class
- •Property Procedures
- •Customizing Default Members
- •Custom Enumerations
- •Using the SimpleClass in Other Projects
- •Firing Events
- •Shared Properties
- •Parsing a Filename String
- •Reusing the StringTools Class
- •Encapsulation and Abstraction
- •Inheritance
- •Inheriting Existing Classes
- •Polymorphism
- •The Shape Class
- •Object Constructors and Destructors
- •Instance and Shared Methods
- •Who Can Inherit What?
- •Parent Class Keywords
- •Derived Class Keyword
- •Parent Class Member Keywords
- •Derived Class Member Keyword
- •MyBase and MyClass
- •Summary
- •On Designing Windows Controls
- •Enhancing Existing Controls
- •Building the FocusedTextBox Control
- •Building Compound Controls
- •VB.NET at Work: The ColorEdit Control
- •VB.NET at Work: The Label3D Control
- •Raising Events
- •Using the Custom Control in Other Projects
- •VB.NET at Work: The Alarm Control
- •Designing Irregularly Shaped Controls
- •Designing Owner-Drawn Menus
- •Designing Owner-Drawn ListBox Controls
- •Using ActiveX Controls
- •Summary
- •Programming Word
- •Objects That Represent Text
- •The Documents Collection and the Document Object
- •Spell-Checking Documents
- •Programming Excel
- •The Worksheets Collection and the Worksheet Object
- •The Range Object
- •Using Excel as a Math Parser
- •Programming Outlook
- •Retrieving Information
- •Recursive Scanning of the Contacts Folder
- •Summary
- •Advanced Array Topics
- •Sorting Arrays
- •Searching Arrays
- •Other Array Operations
- •Array Limitations
- •The ArrayList Collection
- •Creating an ArrayList
- •Adding and Removing Items
- •The HashTable Collection
- •VB.NET at Work: The WordFrequencies Project
- •The SortedList Class
- •The IEnumerator and IComparer Interfaces
- •Enumerating Collections
- •Custom Sorting
- •Custom Sorting of a SortedList
- •The Serialization Class
- •Serializing Individual Objects
- •Serializing a Collection
- •Deserializing Objects
- •Summary
- •Handling Strings and Characters
- •The Char Class
- •The String Class
- •The StringBuilder Class
- •VB.NET at Work: The StringReversal Project
- •VB.NET at Work: The CountWords Project
- •Handling Dates
- •The DateTime Class
- •The TimeSpan Class
- •VB.NET at Work: Timing Operations
- •Summary
- •Accessing Folders and Files
- •The Directory Class
- •The File Class
- •The DirectoryInfo Class
- •The FileInfo Class
- •The Path Class
- •VB.NET at Work: The CustomExplorer Project
- •Accessing Files
- •The FileStream Object
- •The StreamWriter Object
- •The StreamReader Object
- •Sending Data to a File
- •The BinaryWriter Object
- •The BinaryReader Object
- •VB.NET at Work: The RecordSave Project
- •The FileSystemWatcher Component
- •Properties
- •Events
- •VB.NET at Work: The FileSystemWatcher Project
- •Summary
- •Displaying Images
- •The Image Object
- •Exchanging Images through the Clipboard
- •Drawing with GDI+
- •The Basic Drawing Objects
- •Drawing Shapes
- •Drawing Methods
- •Gradients
- •Coordinate Transformations
- •Specifying Transformations
- •VB.NET at Work: Plotting Functions
- •Bitmaps
- •Specifying Colors
- •Defining Colors
- •Processing Bitmaps
- •Summary
- •The Printing Objects
- •PrintDocument
- •PrintDialog
- •PageSetupDialog
- •PrintPreviewDialog
- •PrintPreviewControl
- •Printer and Page Properties
- •Page Geometry
- •Printing Examples
- •Printing Tabular Data
- •Printing Plain Text
- •Printing Bitmaps
- •Using the PrintPreviewControl
- •Summary
- •Examining the Advanced Controls
- •How Tree Structures Work
- •The ImageList Control
- •The TreeView Control
- •Adding New Items at Design Time
- •Adding New Items at Runtime
- •Assigning Images to Nodes
- •Scanning the TreeView Control
- •The ListView Control
- •The Columns Collection
- •The ListItem Object
- •The Items Collection
- •The SubItems Collection
- •Summary
- •Types of Errors
- •Design-Time Errors
- •Runtime Errors
- •Logic Errors
- •Exceptions and Structured Exception Handling
- •Studying an Exception
- •Getting a Handle on this Exception
- •Finally (!)
- •Customizing Exception Handling
- •Throwing Your Own Exceptions
- •Debugging
- •Breakpoints
- •Stepping Through
- •The Local and Watch Windows
- •Summary
- •Basic Concepts
- •Recursion in Real Life
- •A Simple Example
- •Recursion by Mistake
- •Scanning Folders Recursively
- •Describing a Recursive Procedure
- •Translating the Description to Code
- •The Stack Mechanism
- •Stack Defined
- •Recursive Programming and the Stack
- •Passing Arguments through the Stack
- •Special Issues in Recursive Programming
- •Knowing When to Use Recursive Programming
- •Summary
- •MDI Applications: The Basics
- •Building an MDI Application
- •Built-In Capabilities of MDI Applications
- •Accessing Child Forms
- •Ending an MDI Application
- •A Scrollable PictureBox
- •Summary
- •What Is a Database?
- •Relational Databases
- •Exploring the Northwind Database
- •Exploring the Pubs Database
- •Understanding Relations
- •The Server Explorer
- •Working with Tables
- •Relationships, Indices, and Constraints
- •Structured Query Language
- •Executing SQL Statements
- •Selection Queries
- •Calculated Fields
- •SQL Joins
- •Action Queries
- •The Query Builder
- •The Query Builder Interface
- •SQL at Work: Calculating Sums
- •SQL at Work: Counting Rows
- •Limiting the Selection
- •Parameterized Queries
- •Calculated Columns
- •Specifying Left, Right, and Inner Joins
- •Stored Procedures
- •Summary
- •How About XML?
- •Creating a DataSet
- •The DataGrid Control
- •Data Binding
- •VB.NET at Work: The ViewEditCustomers Project
- •Binding Complex Controls
- •Programming the DataAdapter Object
- •The Command Objects
- •The Command and DataReader Objects
- •VB.NET at Work: The DataReader Project
- •VB.NET at Work: The StoredProcedure Project
- •Summary
- •The Structure of a DataSet
- •Navigating the Tables of a DataSet
- •Updating DataSets
- •The DataForm Wizard
- •Handling Identity Fields
- •Transactions
- •Performing Update Operations
- •Updating Tables Manually
- •Building and Using Custom DataSets
- •Summary
- •An HTML Primer
- •HTML Code Elements
- •Server-Client Interaction
- •The Structure of HTML Documents
- •URLs and Hyperlinks
- •The Basic HTML Tags
- •Inserting Graphics
- •Tables
- •Forms and Controls
- •Processing Requests on the Server
- •Building a Web Application
- •Interacting with a Web Application
- •Maintaining State
- •The Web Controls
- •The ASP.NET Objects
- •The Page Object
- •The Response Object
- •The Request Object
- •The Server Object
- •Using Cookies
- •Handling Multiple Forms in Web Applications
- •Summary
- •The Data-Bound Web Controls
- •Simple Data Binding
- •Binding to DataSets
- •Is It a Grid, or a Table?
- •Getting Orders on the Web
- •The Forms of the ProductSearch Application
- •Paging Large DataSets
- •Customizing the Appearance of the DataGrid Control
- •Programming the Select Button
- •Summary
- •How to Serve the Web
- •Building a Web Service
- •Consuming the Web Service
- •Maintaining State in Web Services
- •A Data-Driven Web Service
- •Consuming the Products Web Service in VB
- •Summary
870 Chapter 20 DATABASES: ARCHITECTURE AND BASIC CONCEPTS
this chapter isn’t just of theoretical interest. Everything you will learn in this chapter is as practical as it gets.
Another important motivation for this chapter is the fact that databases, the most important aspect of computer science today, are among the most complicated objects in programming, yet they’re based on common-sense principles. Once you’ve understood these principles, you’ll find that database programming isn’t as complicated as you may have thought.
What Is a Database?
A database is an object for storing complex, structured information. The same is true for a file, or even for the file system on your hard disk. What makes a database unique is the fact that databases are designed to make data easily retrievable. The purpose of a database is not so much the storage of information as its quick retrieval. In other words, you must structure your database so that it can be queried quickly and efficiently.
Databases are maintained by special programs, such as Access and SQL Server. These programs are called database management systems (DBMS), and they’re among the most complicated applications. A fundamental characteristic of a DBMS is that it isolates much of the complexity of the database from the developer. Regardless of how each DBMS stores data on disk, you see your data organized in tables with relationships between tables. To access the data stored in the database and to update the database, you use a special language, Structured Query Language (SQL). Unlike other areas of programming, SQL is a truly universal language and all major DBMSs support this language.
Note The recommended DBMS for Visual Studio .NET is SQL Server 2000. You can use Access, or even nonMicrosoft databases like Oracle. Although this chapter was written with SQL Server 2000, most of the examples will work with Access 2000 as well.
Data are stored in tables, and each table contains entities of the same type. In a database that stores information about books, there will be a table with titles, another table with authors, and a table with publishers. The table with the titles contains information like the title of the book, number of pages, and the book’s description. Author names are stored in a different table, because each author may appear in multiple titles. If author information were stored along with each title, we’d be repeating author names. This means that every time we wanted to change an author’s name, we’d have to modify multiple entries in the titles table. Even retrieving a list of unique author names would be a challenge, because you’d have to scan the entire database, retrieve all the authors, and then get rid of the duplicates entries. The same is true for publishers. Publishers are stored in a separate table, and each title contains a pointer to the appropriate row in the publishers table. If publisher information was stored along with each title, then deleting all the books of a specific publisher would also remove the information about the specific publisher from the database.
The reason for breaking the information we want to store in a database into separate tables is to avoid duplication of information. This is a key point in database design. Duplication of information will sooner or later lead to inconsistencies in the database. The process of breaking the data into related tables that eliminate all possible forms of information duplication is called normalization, and there rules for normalizing databases. The topic of database normalization is not discussed in this book. However, all it really takes to design a functional database is common sense. Once you learn
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
WHAT IS A DATABASE? 871
how to extract data from your database’s tables with SQL statements, you’ll develop a better understanding of how databases should be structured.
Breaking the information into separate tables is a very convenient approach, but we must figure out a way to reconstruct the information. For each title, we must retrieve the title’s author(s) and publisher and put them together to display all the information about the book. To be able to reconstruct the original information, we establish links between the various tables. These links are called relationships, and they’re at the heart of a modern DBMS.
Relational Databases
The databases we’re interested in are relational, because they are based on relationships among the data they contain. The data is stored in tables, and tables contain related data, or entities, such as persons, products, orders, and so on. The idea is to keep the tables small and manageable; thus, separate entities are kept in their own tables. If you start mixing customers and invoices, products and their suppliers, or books, publishers, and authors in the same table, you’ll end up repeating information—a highly undesirable situation. If there’s one rule to live by as a database designer and programmer, this is it: Do not duplicate information.
Of course, entities are not independent of each other. For example, orders are placed by specific customers, so the rows of the Customers table must be linked to the rows of the Orders table that store the orders of the customers. Figure 20.1 shows a segment of a table with customers (top left) and the rows of a table with orders that correspond to one of the customers (bottom right). The lines that connect the rows of the two tables represent relationships.
Figure 20.1
Linking customers and orders with relationships
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
872 Chapter 20 DATABASES: ARCHITECTURE AND BASIC CONCEPTS
As you can see in Figure 20.1, relationships are implemented by inserting columns with matching values in the two related tables; the CustomerID column is repeated in both tables. The rows with a common value in their CustomerID field are related. In other words, the lines that connect the two tables simply indicate that there are two fields, one on each side of the relationship, with a common value. The customer with the ID value BERGS has placed the orders 10278 and 10280. The customer BSBEV has placed the order 10289. To find all the orders placed by a customer, we can scan the Orders table and retrieve the rows in which the CustomerID field has the same value as the ID of the specific customer in the Customers table. Likewise, you can locate customer information for each order by looking up the row of the Customers table that has the same ID as the one in the CustomerID field of the Orders table.
These two fields used in a relationship are called key fields. The CustomerID field of the Customers table is the primary key, because it identifies a single customer. The CustomerID field of the Orders table is the foreign key of the relationship. A CustomerID value appears in a single row of the Customers table; it’s the table’s primary key. However, it may appear in multiple rows of the Orders table, because in this table the CustomerID field is the foreign key. In fact, it will appear in as many rows of the Orders table as there are orders for the specific customer.
The operation of matching rows in two tables based on their primary and foreign keys is called a join. Joins are very basic operations in manipulating tables, and they are discussed in detail in the section “Structured Query Language,” later in this chapter.
Exploring the Northwind Database
In this section, we’ll explore the structure of a sample database that comes with both SQL Server 2000 and Access 2000. The Northwind database stores products, customers, and sales data, and many of you are already familiar with the structure of the database. We’ll discuss the basic objects that make up a database shortly, but it’s easier to explain these objects through examples. Besides, you need a good understanding of the structure of this database, so that you can follow the examples of the following sections and chapters. Unless you understand how data is stored in the tables of the database and how the tables relate to one another, you won’t be able to retrieve information from the database or insert new data into it.
The Northwind database is made up of tables, each storing a collection of unique entities (customers, products, and so on). A table that stores products has a column for the product’s name, another column for the product’s price, and so on. Each product is stored in a different row. As products are added or removed from the table, the number of rows changes, but the number of columns remains the same; they determine the information we store about each product.
Products Table
The Products table stores information about the products sold by the Northwind Corporation. This information includes the product’s name, packaging information, price, and other relevant fields. Each product (or row) in the table is identified by a unique numeric ID. Since the rows of the Products table are referenced by invoices (the Order Details table, which is discussed later), the product IDs appear in the Order Details table as well.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
WHAT IS A DATABASE? 873
Suppliers Table
Each product has a supplier too. Because the same supplier may offer more than one product, the supplier information is stored in a different table, and a common field, the SupplierID field, is used to link each product to its supplier as shown in Figure 20.2. For example, the products Chai, Chang, and Aniseed Syrup are purchased from the same supplier, Exotic Liquids. Their SupplierID fields all point to the same row in the Suppliers table.
Figure 20.2
Linking products to their suppliers and their categories
Categories Table
In addition to having a supplier, each product belongs to a category. Categories are not stored along with product names, but in a separate table, the Categories table. Again, each category is identified by a numeric value (field CategoryID) and has a name (field CategoryName). In addition, the Categories table has two more columns: Description, which contains text, and Picture, which stores a bitmap. The CategoryID field in the Categories table is the primary key, and the field by the same name in the Products table is the corresponding foreign key.
Customers Table
The Customers table stores information about the company’s customers. Each customer is stored in a separate row of this table, and customers are referenced by the Orders table. Unlike the product IDs, the customer IDs are five-character strings.
Orders Table
The Orders table stores information about the orders placed by Northwind’s customers. The OrderID field, which is an integer value, identifies each order. Orders are numbered sequentially, so this field is also the order’s number. Each time you append a new row to the Orders table, the value of the new OrderID field is generated automatically by the database.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
874 Chapter 20 DATABASES: ARCHITECTURE AND BASIC CONCEPTS
The Orders table is linked to the Customers table through the CustomerID field. By matching rows with identical values in their CustomerID fields in the two tables, we can recombine customers with their orders. Figure 20.1 shows how customers are linked to their orders.
Order Details Table
You probably have noticed that the Northwind database’s Orders table doesn’t store any details about the items ordered. This information is stored in the Order Details table (see Figure 20.3). Each order is made up of one or more items, and each item has a price, a quantity, and a discount. In addition to these fields, the Order Details table contains an OrderID column, which holds the ID of the order to which the detail line belongs.
Figure 20.3
The Customers, Orders, and Order Details tables, and their relations
The reason details aren’t stored along with the order’s header is that the Orders and Order Details tables store different entities. The order’s header, which contains information about the customer who placed the order, the date of the order, and so on, is quite different from the information you must store for each item ordered.
Employees Table
This table holds employee information. Each employee is identified by a numeric ID, which appears in the each order. When a sale is made, the ID of the employee who made the sale is recorded in the Orders table.
Shippers Table
Each order is shipped with one of the three shippers stored in the Shippers table. The appropriate shipper’s ID is stored in the Orders table.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |