Database Design – The ER Model

The Entity-Relationship Model is a data model that helps us describe the organization of data for a particular scenario (business, or some other need).  It was developed by Peter Chen and originally published in 1976.  What we get is an abstract representation of the data by viewing the problem in terms of entities and relationships (that exist among the entities).  Here are some good references for the ER Model:

Some terms and concepts to pay attention to:

  • Entity vs. Entity Set
  • Relationship vs. Relationship Set
  • Attribute
  • Key, Primary Key, etc.
  • Relationship Cardinalities (1:1, 1:M, M:N)
  • Relationship Constraints (Total or Partial)

Different ER Model Notations:

 

SQL

SQL is the language of relational databases.  Solving problems efficiently with SQL will require you to think in sets rather than procedurally.  Hopefully our foray into relational algebra has helped you hone those skills.  Some reading:

  • Pro MySQL by Kruckenberg and Pipes (APress Publisher) – Chapter 7: Essential SQL.  The book is available in PDF through the SMU Central University Libraries Website.
  • SQL Tutorial

The Relational Model

As we being our foray into the world of database systems, our first stop is at the Relational Model of Data.  In the relational model, some of the basic components are tuples, relations, and relationships.  It was originally developed and proposed in the late 60’s by E. F. Codd.  Perhaps one of the most influential papers related to the relational model is Codd’s “A Relational Model of Data for Large Shared Data Banks“.

Here are some of the topics we will cover right now [Read more…]

Command Line Args in C++

As you’re already familiar with, when you call some functions, you need to pass arguments to them.  So, what about main?  There are two different function headers for he main method in C++ that we can use:

int main (); //header 1

and

int main(int argc, char* argv[]); //header 2

Now, you should ask yourself, “What’s the difference?”  Remember that when you execute a program (either from the command line or by double-clicking on an icon or something similar), you’re really asking the OS to load the executable and begin execution.  When the OS is starting your program, you can use command line arguments to send arguments into the main method.  Consider this program execution:

./myFunGame input.txt output.txt

[Read more…]

Data Structures Intro

The first few weeks of the semester, we’ll take a deep(er) dive into pointers and dynamic memory management using C++.  To get started, I wanted to provide you some links to useful information.

Regarding our first topic, pointers and memory management, here are some links to some other blog posts I did over the summer that might be helpful:

Objects and Pointers

Some of the previous videos and reading have covered the implications of an object owning some dynamically allocated memory.  Mainly, what I’m referring to here is the need for a copy constructor, overloaded assignment operator, and destructor in a class that contains any dynamically allocated memory.  That’s all important stuff.  Know it, learn it, love it.

But what about the dynamic allocation of objects themselves – how does it work and what are the implications.  I’m glad you asked. Dynamically allocating an object is just like dynamically allocating anything else.   [Read more…]

Object-Oriented Programming in C++

C++ was originally called “c with classes” meaning that it was everything that the c language was plus the ability to create classes and objects in the language.  I’m sure that you can see the value in creating a higher level construct over and above a simple variable.  For example, if we were modeling the data for a group of workers at a company, we would want to keep track of a number of different things about each employee: name, address, employee id number, yearly salary, and department perhaps.  We could make use of the concept of parallel arrays meaning that we have 2 or more arrays whose elements are related via their position (or subscript) in the array.  So, name[9], empID[9], salary[9], etc would all refer to data about the same employee because each is being accessed with the same subscript.  However, after a while, this becomes cumbersome and isn’t very extensible as we add new variables to track.  [Read more…]

Arrays of c-strings

There are a lot of use cases in which you deal with a set of strings.  An array of strings seems to be a logical, first-pass choice for storing them.  Because c-strings are basic arrays fundamentally, they are a great topic to use to understand the array/pointer relationship more fully.

Consider, the following array declaration:

char data[5][10] = {"red", "yellow", "green", "blue", "violet"};

Because data is the name of a 2D array, it can be treated as a pointer to a pointer, or more precisely in this case, a pointer to an array of pointers.  Because we are dealing with a 2D array of chars with each row acting as a null-terminated c-string, then we can also conceptualize data as an array of c-strings.  So, if I have an array of c-strings, then I can display just one c-string from the array by sending the address of the 1st element of the array to cout like this:

cout << data[1] << endl; //would print yellow

Remember, if you send an ostream object a char pointer, it will start printing at that character until it gets to a null terminator.  This means that if we send it the address of the first letter of a row and an additional offset (but not subscripted), it will start printing at that letter and go to the null terminator as well.  Here is an example:

cout << data[2] + 2 << endl; //would print een of green

The expression data[2]+2 is the memory address of the 3rd character in the 3rd string of the array.  Therefore, it will start printing at that character and print until the end of the string.

You may be asking yourself, “What’s the difference between the example above and data[2][2]?”  Great question!  The difference is that in data[2][2], the 2nd number is subscripted, which means essentially that it is dereferenced.  So, the data type of the expression data[2]+2 is char* while the data type of the expression data[2][2] is char.  If we send cout a char, it will only print that one character.

Pointer Offset Notation and Subscript Notation

As we know,

data[2]

is equivalent to

*(data + 2)

One first is subscript notation, then second is pointer-offset notation.  We can include multiple levels of offsets depending on the data type of the base constructs (the datatype of data, in this case).  So, this means that the expression

data[2][2]

is equivalent to the expression

*(*(data + 2)+2)

If you think about starting at the deepest level of nesting and work your way out, you’ll see that they are equivalent.

As an example, the following two statements produce the same output:

cout << (data[1] + 3) << endl;
cout << (*(data+1)+3) << endl;

The relationship between pointer-offset notation and subscript notation can seem to be a little confusing.  But if you just take it slow, it all makes logical sense.

Peace, love, c++!

Memory Management in C++

C++ gives you, the programmer, more fine-grained access to memory than a language like Java.  An old saying goes like this, “To whom much is give, much is expected.”  So, because you have more control over memory, you have to take care to handle it appropriately.  This means that if you dynamically allocate memory, you should de-allocate it when you’re done with it.

Here are a few YouTube videos that are similar to stuff I’ve talked about.  But hearing the info explained a little differently might be helpful.

Basic Dynamic Allocation and Deallocation:  Video

Memory Leaks and Dangling Pointers: Video (The writing is a little bit hard to read, but it is a good explanation)

Pointers to Pointers: Video (Same issue as above, but good expl).

It’s Not Nice to Point… But Really, It’s OK.

Pointers are really important to the C and C++ language.  They are actually really important in many different languages whether or not you have direct access to manipulate them. In our on-line gathering yesterday evening, I introduced you to the basic concepts of pointers and memory layout, well – at least how C++ sees it.

It’s time to read Section 6.3 of Overland (skip 6.3.7, 6.3.8 and 6.3.9). Also read Section 6.4, but stop before the paragraph that starts with “This analysis—what would the item imply…”.  From that point down is about function pointers which should be in its own sub section.  But in any event, you don’t need to worry about these. 

Here are a couple videos that might also be useful to you that I made a few semesters ago: Video 1, Video 2.

Reading sections 10.1, 10.2, and 10.3 of Overland related to c-strings could be helpful if you need more info there.