⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch13.htm

📁 好书《C++ Builder高级编程技术》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>

<HEAD>
	<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
	<META NAME="Author" Content="Steph Mineart">
	<TITLE>Ch 13 -- Flat-File, Real-World Databases</TITLE>
</HEAD>


<BODY BACKGROUND="bg1.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/bg1.gif" BGCOLOR="#FFFFFF">

<P ALIGN="CENTER"><IMG SRC="sams.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/sams.gif" WIDTH="75" HEIGHT="24" ALIGN="BOTTOM"
BORDER="0"><BR>
<BR>
<A HREF="index-3.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/index.htm"><IMG SRC="toc.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/toc.gif" WIDTH="40" HEIGHT="40" ALIGN="BOTTOM"

ALT="TOC" BORDER="0" NAME="toc4"></A><A HREF="ch12.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/ch12.htm"><IMG SRC="back-1.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/back.gif"
WIDTH="40" HEIGHT="40" ALIGN="BOTTOM" ALT="BACK" BORDER="0" NAME="toc1"></A><A HREF="ch14.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/ch14.htm"><IMG
SRC="forward.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/forward.gif" WIDTH="40" HEIGHT="40" ALIGN="BOTTOM" 
ALT="FORWARD" BORDER="0"
NAME="toc2"></A></P>
<H2 ALIGN="CENTER"><FONT COLOR="#000077">Charlie Calvert's C++ Builder Unleashed</FONT></H2>
<P>
<H2 ALIGN="CENTER"><A NAME="Heading1"></A><FONT COLOR="#000077">- 13 -</FONT></H2>
<H2 ALIGN="CENTER"><A 
NAME="Heading2"></A><FONT COLOR="#000077">Flat-File, Real-World
Databases</FONT></H2>
<P>
<H3><A NAME="Heading3"></A><FONT COLOR="#000077">Overview</FONT></H3>
<P>This chapter is the first of a &quot;two-part series&quot; on constructing real-world

databases. The goal is to move from the largely theoretical information you got in
the preceding chapter into a few examples of how to make programs that someone could
actually use for a practical purpose in the real world.</P>
<P>In several sections 
of this chapter, I go into considerable depth about design-related
issues. One of the burdens of this chapter is not merely to show how database code
works, but to talk about how to create programs that have some viable use in the
real world. These 
design-related issues are among the most important that any programmer
will ever face.</P>
<P>In this chapter, you will get a look at a simple, nearly pure, flat-file address
book program called Address2. This program is designed to represent the 
simplest
possible database program that is still usable in a real-world situation. In the
next chapter, I will create a second address program, designed to be a &quot;killer&quot;
relational database with much more power than the one you see in this 
chapter.</P>
<P>One of my primary goals in these two chapters is to lay out in the starkest possible
terms the key differences between flat-file and relational databases. The point is
for you to examine two database tools that perform the same task 
and see exactly
what the relational tool brings to the table. I found, however, that it was simply
impossible for me to create a completely flat-file database design. As a result,
I had to content myself with a design that was nearly a pure example of 
a flat-file
database. It does, however, contain one smaller helper table that is linked in using
relational database design principles. My simple inability to omit this table does
more than anything else I can say to stress the weaknesses of the 
flat-file model,
and to show why relational databases are essential.</P>
<P>The second database program you see will contain a very powerful set of relational
features that could, with the aid of a polished interface, stand up under the strain
of 
heavy and complex demands. You could give this second program to a corporate secretary
or executive, and that person could make some real use of it. The database shown
in this chapter, on the other hand, is meant to be a quick solution to a simple 
problem.
One of the points you shouldn't miss, however, is that the database from this chapter
more than suits the needs of most people.</P>
<P>One of the classic and most commonly made mistakes is to give people too many
features, or to concentrate 
on the wrong set of features. Those of us who work in
the industry forget how little experience most users have with computers. Even the
simple database program outlined in this chapter might be too much for some people.
Any attempt to sell them on 
the merits of the database from the next chapter would
simply be an exercise in futility. They would never be willing to take the time to
figure out what to do with it. As a result, I suggest that you not turn your nose
up at the database shown in 
this chapter just because it is not as powerful as the
one in the next chapter. Just because your typical Volkswagen is not as powerful
as an Alpha Romeo does not mean that the Volkswagen people are in a small business
niche, or even that there is 
less money in VWs than in Alpha Romeos.</P>
<P>Here is a quick look at the terrain covered in this chapter:

<UL>
	<LI>Sorting data.
	<P>
	<LI>Filtering data.
	<P>
	<LI>Searching for data.
	<P>
	<LI>Dynamically moving a table in and out of a read-only 
state.
	<P>
	<LI>Forcing the user to select a field's value from a list of valid responses.
	<P>
	<LI>Allowing the user to choose the colors of a form at runtime.
	<P>
	<LI>Saving information to the Registry. In particular, you see how to use the 
Registry
	to replace an INI file, and how to save and restore information from and to the Registry
	at program startup.
	<P>
	<LI>Using events that occur in a <TT>TDataModule</TT> inside the main form of your
	program. That is, the chapter shows how 
to respond to events specific to one form
	from inside a second form. Or, more generally, it shows how to handle events manually
	rather than let BCB set up the event handler for you.
</UL>

<P>After finishing this chapter, you will have learned 
something about the kinds
of problems experienced when writing even a very basic database program that serves
a real-world purpose. The final product, though not quite up to professional standards,
provides solutions to many of the major problems 
faced by programmers who want to
create tools that can be used by the typical user. In particular, the program explores
how to use BCB to create a reasonably usable interface.</P>
<P>You will find that the final program is relatively long when 
compared to most
of the programs you have seen so far in this book. The length of the program is a
result of my aspiration to make it useful in a real-world setting, while simultaneously
providing at least a minimum degree of robustness. The act of 
adding a few niceties
to the interface for a program gives you a chance to see how RAD programming can
help solve some fairly difficult problems.</P>
<P>Before closing this overview, I should perhaps explicitly mention that this chapter
does not cover 
printing, which is certainly one of the most essential real-world
needs for a database program. I will, however, add printing capabilities to this
program in Chapter 17, &quot;Printing: QuickReport and Related Technologies.&quot;
In fact, that chapter 
will show how to add printing to all the useful database programs
that will be created in the next few chapters of this book. My plan is to isolate
the important, even crucial, subject of printing in its own chapter where it can
be properly 
addressed.</P>
<P>You should also be sure you have read the readme files on the CD that accompanies
this book for information about the alias used in the Address2 program and in other
programs in this book. If you have trouble getting any of these 
programs running,
be sure to check my Web site (<A HREF="javascript:if(confirm('http://users.aol.com/charliecal  \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address.  \n\nDo you want to open it from the server?'))window.location='http://users.aol.com/charliecal'" tppabs="http://users.aol.com/charliecal"><TT>users.aol.com/charliecal</TT></A>)
for possible updates.
<H3><A NAME="Heading4"></A><FONT COLOR="#000077">Defining the Data</FONT></H3>
<P>When you're 
considering an address program, you can easily come up with a preliminary
list of needed fields:</P>
<PRE><FONT COLOR="#0066FF">First Name

Last Name

Address

City

State

Zip

Phone

</FONT></PRE>
<P>After making this list and contemplating it for a 
moment, you might ask the following
questions:

<UL>
	<LI>What about complex addresses that can't be written on one line?
	<P>
	<LI>Is one phone number enough? What about times when I need a home phone and a work
	phone?
	<P>
	<LI>Speaking of work, 
what about specifying the name of the company that employs
	someone on the list?
	<P>
	<LI>What about faxes?
	<P>
	<LI>This is the 1990s, so what about an e-mail address?
	<P>
	<LI>What about generic information that doesn't fit into any of these 
categories?
</UL>

<P>This list of questions emerges only after a period of gestation. In a real-world
situation, you might come up with a list of questions like this only after you talk
with potential users of your program, after viewing similar 
programs that are on
the market, and after experimenting with a prototype of the proposed program. Further
information might be culled from your own experience using or writing similar programs.
Whatever way you come up with the proper questions, the 
key point is that you spend
the time to really think about the kind of data you need.

<DL>
	<DT></DT>
</DL>



<BLOCKQUOTE>
	<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>Many books tell you to complete
	your plan before you begin 
programming. The only thing wrong with this theory is
	that I have never seen it work out as expected in practice. <BR>
	<BR>
	Nearly all the real-world programs that I have seen, both my own and others, whether
	produced by individuals or huge 
companies, always seem to go through initial phases
	that are later abandoned in favor of more sophisticated designs. This is part of
	what Delphi and RAD programs in general are all about. They make it possible for
	you to create a draft of your 
program and then rewrite it. <BR>
	<BR>
	Think hard about what you want to do. Then get up a prototype in fairly short order,
	critique it, and then rethink your design. Totally abandoning the first draft is
	rarely necessary, but you are almost 
certainly going to have to rewrite. For this
	reason, concentrating on details at first is not a good idea. Get things up and running;
	then if they look okay, go back and optimize. <BR>
	<BR>
	The point is that the process is iterative. You keep 
rewriting, over and over, the
	same way authors keep rewriting the chapters in their books. RAD programming tools
	help make this kind of cycle possible. The interesting thing about Delphi is that
	the same tool that lets you prototype quickly is also 
the tool that lets you optimize
	down to the last clock cycle. <BR>
	<BR>
	I don't, however, think most contemporary application programming is really about
	optimization any more than it's about attempting to design a program correctly on
	paper 
before writing it. My experience leads me to believe that the practical plan
	that really works is iterative programming. Think for a little bit and then write
	some code. Review it, then rewrite it, then review it, and then rewrite it, and so
	on. 
Another, somewhat more old-fashioned name for this process is simply: One heck
	of a lot of hard work! 
<HR>


</BLOCKQUOTE>

<P>After considering the preceding questions, you might come up with a revised list
of fields for your program:</P>

<PRE><FONT COLOR="#0066FF">First Name

Last Name

Company

Address1

Address2

City

State

Zip

Home Phone

Work Phone

Fax

EMail1

EMail2

Comment

</FONT></PRE>
<P>This list might actually stand up to the needs of a real-world user. Certainly,
it 
doesn't cover all possible situations, but it does represent a reasonable compromise
between the desire to make the program easy to use and the desire to handle a variety
of potential user demands.</P>
<P>At this stage, you might start thinking about 
some of the basic functionality
you want to associate with the program. For example, you might decide that a user
of the program should be able to search, sort, filter, and print the data. After
stating these needs, you'll find that the user will need 
to break up the data into
various categories so that it can be filtered. The question, of course, is how these
categories can be defined.</P>
<P>After considering the matter for some time, you might decide that two more fields
should be added to the 
list. The first field can be called <TT>Category</TT>; it
holds a name that describes the type of record currently being viewed. For example,
some entries in an address book might consist of family members, whereas other entries
might reference 
friends, associates from work, companies where you shop, or other
types of data. A second field can be called <TT>Marked</TT>; it designates whether
a particular field is marked for some special processing.</P>
<P>Here is the revised list, with one 
additional field called <TT>Category</TT>,
that is used to help the user filter the data he or she might be viewing:</P>
<PRE><FONT COLOR="#0066FF">First Name

Last Name

Company

Address1

Address2

City

State

Zip

Home Phone

Work Phone

Fax


EMail1

EMail2

Comment

Category

Marked

</FONT></PRE>
<P>After you carefully consider the fields that might be used in the Address2 program,
the next step is to decide how large and what type the fields should be. Table 13.1
shows proposed types 
and sizes. <BR>
<BR>
<B>Table 13.1. The lengths and types of fields used by the Address2 program. </B>
<TABLE BORDER="1">
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><B>Name</B></TD>
		<TD WIDTH="96" ALIGN="LEFT"><B>Type</B></TD>
		
<TD WIDTH="59" ALIGN="LEFT"><B>Size</B></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>FName</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">40</TD>
	</TR>
	<TR ALIGN="LEFT" 
rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>LName</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">40</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>Company</TT></TD>
		<TD 
WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">40</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>Address1</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">40</TD>
	
</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>Address2</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">40</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" 
ALIGN="LEFT"><TT>City</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">40</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>State</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		
<TD WIDTH="59" ALIGN="LEFT">5</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>Zip</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">15</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD 
WIDTH="85" ALIGN="LEFT"><TT>HPhone</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">15</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>WPhone</TT></TD>
		<TD WIDTH="96" 
ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">15</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>Fax</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">15</TD>
	</TR>
	<TR 
ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>EMail1</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">45</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>EMail2</TT></TD>
		
<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">45</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>Comment</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Memo</TD>
		<TD WIDTH="59" ALIGN="LEFT">20</TD>
	
</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" ALIGN="LEFT"><TT>Category</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Character</TD>
		<TD WIDTH="59" ALIGN="LEFT">15</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="85" 
ALIGN="LEFT"><TT>Marked</TT></TD>
		<TD WIDTH="96" ALIGN="LEFT">Logical</TD>
		<TD WIDTH="59" ALIGN="LEFT"></TD>
	</TR>
</TABLE>
<BR>
<BR>
As you can see, I prefer to give myself plenty of room in all the fields I declare.
In particular, notice that I 
have opted for wide <TT>EMail</TT> fields to hold long
Internet addresses, and I have decided to make the <TT>Comment</TT> field into a
memo field so that it can contain long entries, if necessary. The names of some of
the fields have also been 
altered so that they don't contain any spaces. This feature
might prove useful if the data is ever ported to another database.</P>
<P>Now that you have decided on the basic structure of the table, the next task is
to work out some of the major design 
issues. In particular, the following considerations

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -