Table design

M

MikeR

I need help in designing a back-end that will be used to score a contest my amateur
radio club is having. It will be on the web, accessed using ASP.

The goal for the members is to contact another ham station in each of 344 countries.
Each country is in a zone (40).
I have a table with the countries and associated zone, and each country has a unique ID.

For each contact for each member I need to be able to report the country, callsign,
date/time, and zone of the station worked.

How best to define the table(s) to do this? I don't want a giant spreadsheet.

Thanks, Mike
 
S

Stefan Hoffmann

hi Mike,
The goal for the members is to contact another ham station in each of
344 countries. Each country is in a zone (40).
So you have

Zones 1 -> n Countries 1 -> n Stations

if "a zone" means one zone.

I assume that stations and members are aquivalent?
How best to define the table(s) to do this? I don't want a giant
spreadsheet.

Zone:
ID (PK, Autonumber)
Zone (Text(), not NULL)

Country:
ID (PK, Autonumber)
Zone_ID (FK, Long, not NULL)
Country (Text(), not NULL)
UniqueID (Unique Index, not NULL)

If your unique country ID is a number of type Long, then you may use it
instead of the Autonumber as primary key field.

Station:
ID (PK, Autonumber)
Country_ID (FK, Long, not NULL)
Callsign (Unique Index, Text(), not NULL)
For each contact for each member I need to be able to report the
country, callsign, date/time, and zone of the station worked.
You don't need to report the zone, if your description was correct.

Contact:
ID (PK, Autonumber)
Station_ID (FK, not NULL)
ContactAt (Date/Time, not NULL)



mfG
--> stefan <--
 
M

MikeR

Hi Stefan, and thanks -
Stefan said:
hi Mike,

So you have

Zones 1 -> n Countries 1 -> n Stations

if "a zone" means one zone. Yes.

I assume that stations and members are aquivalent?
Wellll....No. Everybody has a station. But in my description station belongs to a
non-member, located in one of the countries. As you defined the tables, I think
station and member are the same.
Zone:
ID (PK, Autonumber)
Zone (Text(), not NULL)
I don't understand the purpose of this table.
Country:
ID (PK, Autonumber)
Zone_ID (FK, Long, not NULL)
Country (Text(), not NULL)
UniqueID (Unique Index, not NULL)
An existing table, minus the PK
If your unique country ID is a number of type Long, then you may use it
instead of the Autonumber as primary key field. Nope, it's alpha :-(

Station:
ID (PK, Autonumber)
Country_ID (FK, Long, not NULL)
Callsign (Unique Index, Text(), not NULL)
If this table represents members, Country_ID is not needed.
You don't need to report the zone, if your description was correct.
I need to know which zones a member has contacted, and be able to give a count of
them. For instance I (a member) contact a station (non-member) in each of 12
countries, which are in 5 zones.
Contact:
ID (PK, Autonumber)
Station_ID (FK, not NULL)
ContactAt (Date/Time, not NULL)
Add CallSign to this one, and I think it's OK.

What is the purpose of the all the PK's? This is a very low impact app, and speed is
not an issue.
 
S

Stefan Hoffmann

hi Mike,
What is the purpose of the all the PK's? This is a very low impact app,
and speed is not an issue.
PK means primary key. It ensures uniquness of this value. FK means
foreign key, which you create in the relationships window.


mfG
--> stefan <--
 
M

MikeR

Stefan said:
hi Mike,

PK means primary key. It ensures uniquness of this value. FK means
foreign key, which you create in the relationships window.

I know what the abbreviations stand for. My question was why the PK's are needed in
this instance. The countries table, for instance, already *HAS* another unique ID, as
does Station and Contact

And the rest of my questions/comments?
 
S

Stefan Hoffmann

hi Mike,
I don't understand the purpose of this table.
Zones are entites, at least you can normalize it using DKNF.
I need to know which zones a member has contacted, and be able to give a
count of them. For instance I (a member) contact a station (non-member)
in each of 12 countries, which are in 5 zones.
As your contacting a station/member you know its contry and therefore
its zone.
Add CallSign to this one, and I think it's OK.
This depends on what stations, members and contacts really are. I always
though call signs are per member.
What is the purpose of the all the PK's? This is a very low impact app,
and speed is not an issue.
PK's are not for speed, they're for ensuring uniquness and relational
integrity.


mfG
--> stefan <--
 
S

Stefan Hoffmann

hi Mike,
I know what the abbreviations stand for. My question was why the PK's
are needed in this instance. The countries table, for instance, already
*HAS* another unique ID, as does Station and Contact
You always need a primary key. On the other hand, you don't have posted
that you already have tables. How could I know?

Why don't you post

a) a more precise problem description
b) your solution so far

or vice versa.

mfG
--> stefan <--
 
M

MikeR

Stefan said:
hi Mike,

You always need a primary key.
Why? I'm not questioning your advice, I'm trying to learn.
On the other hand, you don't have posted that you already have tables. How could I know?
From the OP:
I have a table with the countries and associated zone, and each country has a unique ID.
Why don't you post

a) a more precise problem description
A predefined group(23) of stations(members - each identified by a unique callsign)
will each attempt to contact a station(non-members - each identified by a unique
callsign) in each of the 345 countries(defined in the Countries table - each country
has a unique ID). There are roughly 3 million stations worldwide. Each of those
countries is located in a zone, usually multiple countries in a zone. There are 40
zones, numbered 1-40.

I need to record those contacts, and be able to report them:
1) A listing of each contact between a member and a non-member.
2) A count of the number of countries each member has contacted.
3) The number of zones each member has contacted

b) your solution so far
From the OP:
I have a table with the countries and associated zone, and each country has a unique
ID. ;-o
 
M

MikeR

Stefan said:
hi Mike,

Zones are entites, at least you can normalize it using DKNF.
True, zones are entities. What is DKNF?
Countries and zones are related, but I don't see the value of a separate table which
might look like this:
Zone - text
Country_ID(FK to countries table - unique)
14 SP
14 EA
14 F

as opposed to the existing countries table
Country_ID - text PK
Name - text
Zone - text
SP Poland 14
EA Spain 14
F France 14
As your contacting a station/member you know its contry and therefore
its zone.
True. But the number of countries contacted will not (except by coincidence) be the
same as the number of zones.
This depends on what stations, members and contacts really are. I always
though call signs are per member.
Sorry, I meant Zone. Station_ID can be callsign. Every amateur operator has a unique
callsign, the assignment of which is an arcane and fairly non-logical ritual.
PK's are not for speed, they're for ensuring uniquness and relational
integrity.
OK.

I'm getting there, Thanks for your attention to this.
 
S

Stefan Hoffmann

hi Mike,
Why? I'm not questioning your advice, I'm trying to learn. http://en.wikipedia.org/wiki/Database_normalization
http://en.wikipedia.org/wiki/Entity-relationship_model

A predefined group(23) of stations(members - each identified by a unique
callsign) will each attempt to contact a station(non-members - each
identified by a unique callsign) in each of the 345 countries(defined in
the Countries table - each country has a unique ID). There are roughly 3
million stations worldwide. Each of those countries is located in a
zone, usually multiple countries in a zone. There are 40 zones, numbered
1-40.
First of all you have to identify your entities. Here it is especially
necessary to take a closer look at your station/member/non-member
problem. What is a member, what is a non-member?
From the OP:
I have a table with the countries and associated zone, and each country
has a unique ID. ;-o
This is okay when you apply the rules of normalization (1NF-3NF). Your
description indicates that a zone is a entity. So it should be separated
in an extra table. This could be also done applying the Domain Key NF.

The unique ID is normally sufficent as primary key, if it doesn' contain
information. Do you have an example record of your contry table?

This still is valid:

Zones 1 -> n Countries 1 -> n Stations


Maybe Stations and Members are identical, then a table like that maybe
sufficent:

Station: ID, CountryID, CallSign, IsMember


mfG
--> stefan <--
 
M

Michael Gramelspacher

True, zones are entities. What is DKNF?
Countries and zones are related, but I don't see the value of a separate table which
might look like this:
Zone - text
Country_ID(FK to countries table - unique)
14 SP
14 EA
14 F

as opposed to the existing countries table
Country_ID - text PK
Name - text
Zone - text
SP Poland 14
EA Spain 14
F France 14
True. But the number of countries contacted will not (except by coincidence) be the
same as the number of zones.
Sorry, I meant Zone. Station_ID can be callsign. Every amateur operator has a unique
callsign, the assignment of which is an arcane and fairly non-logical ritual.
OK.

I'm getting there, Thanks for your attention to this.

As Stefan asked, wahat is a member, what is a non-member?
Member of what? The designated group?

You can create a new database. Then open query design view and without selecting any tables, select
SQL. Now copy and paste the first CREATE TABLE statement into the window and on the top menubar
select Query and Run. The table is created. In turn do the same for each of the other CREATE TABLE
statements. Just past over what was there before.

When done, open the relationships window and show all the tables. Drag them around so it all makes
sense.

Just take this as an idea. I think it is about right, but maybe not.

CREATE TABLE Countries (
CountryCode CHAR(2) NOT NULL,
CountryName VARCHAR(50) NOT NULL,
CONSTRAINT pk_Countries PRIMARY KEY (CountryCode)
);
CREATE TABLE Zones (
ZoneNumber SMALLINT NOT NULL,
ZoneName VARCHAR(50) NOT NULL,
CONSTRAINT pk_Zones PRIMARY KEY (ZoneNumber)
);
CREATE TABLE CountryZones (
CountryCode CHAR(2) NOT NULL,
CONSTRAINT fk_Countries_CountryZones
FOREIGN KEY (CountryCode) REFERENCES
Countries (CountryCode),
ZoneNumber SMALLINT NOT NULL,
CONSTRAINT fk_Zones_CountryZones
FOREIGN KEY (ZoneNumber) REFERENCES
Zones (ZoneNumber),
CONSTRAINT pk_CountryZones
PRIMARY KEY (CountryCode, ZoneNumber)
);
CREATE TABLE Stations (
CallSign VARCHAR(6) NOT NULL,
OperatorName VARCHAR(50),
CountryCode CHAR(2),
ZoneNumber SMALLINT NOT NULL,
CONSTRAINT fk_CountryZones_Stations
FOREIGN KEY (CountryCode, ZoneNumber) REFERENCES
CountryZones (CountryCode, ZoneNumber),
CONSTRAINT pk_Stations PRIMARY KEY (CallSign)
);
CREATE TABLE DesignatedGroups (
GroupID AUTOINCREMENT NOT NULL,
GroupName VARCHAR(50) NOT NULL,
CONSTRAINT pk_DesignatedGroups PRIMARY KEY (GroupID)
);
CREATE TABLE DesignedGroupMembers (
GroupID LONG NOT NULL,
CONSTRAINT fk_DesignatedGroups_DesignedGroupMembers
FOREIGN KEY (GroupID) REFERENCES
DesignatedGroups (GroupID),
CallSign VARCHAR(6) NOT NULL,
CONSTRAINT StationsDesignedGroupMembers
FOREIGN KEY (CallSign) REFERENCES
Stations (CallSign),
JoinedDate DATETIME NOT NULL,
CONSTRAINT pk_DesignedGroupMembers
PRIMARY KEY (GroupID, CallSign)
);
CREATE TABLE GroupContacts (
GroupID LONG NOT NULL,
CallSign_One VARCHAR(6) NOT NULL,
CONSTRAINT fk_DesignedGroupMembers_GroupContacts
FOREIGN KEY (GroupID, CallSign_One) REFERENCES
DesignedGroupMembers (GroupID, CallSign),
CallSign_Two VARCHAR(6) NOT NULL,
CONSTRAINT fk_Stations_GroupContacts
FOREIGN KEY (CallSign_Two) REFERENCES
Stations (CallSign),
ContactDate DATETIME NOT NULL,
DurationMinutes SMALLINT,
CONSTRAINT pk_GroupContacts
PRIMARY KEY (GroupID, CallSign_One,CallSign_Two,ContactDate)
);
 
M

MikeR

Stefan said:
hi Mike,

http://en.wikipedia.org/wiki/Database_normalization
http://en.wikipedia.org/wiki/Entity-relationship_model Good links. Thanks.

First of all you have to identify your entities. Here it is especially
necessary to take a closer look at your station/member/non-member
problem. What is a member, what is a non-member?

A member is one who has paid dues to the club, and been approved for membership. A
non-member is everyone else in the world.
This is okay when you apply the rules of normalization (1NF-3NF). Your
description indicates that a zone is a entity. So it should be separated
in an extra table. This could be also done applying the Domain Key NF. Erm... What's a Domain Key NF?

The unique ID is normally sufficent as primary key, if it doesn' contain
information. Do you have an example record of your contry table?
From another post in the thread:

Country_ID - text PK
Name - text
Zone - text

for example
SP Poland 14
EA Spain 14
F France 14
This still is valid:

Zones 1 -> n Countries 1 -> n Stations True.


Maybe Stations and Members are identical, then a table like that maybe
sufficent:

Station: ID, CountryID, CallSign, IsMember
OK.
 
M

MikeR

Thanks, Michael -
Comments are below the tables they apply to.

Michael said:
As Stefan asked, wahat is a member, what is a non-member?
Member of what? The designated group? See my answer to Stefan.

You can create a new database. Then open query design view and without selecting any tables, select
SQL. Now copy and paste the first CREATE TABLE statement into the window and on the top menubar
select Query and Run. The table is created. In turn do the same for each of the other CREATE TABLE
statements. Just past over what was there before.
I would actually just use Access to create/define the DB.
When done, open the relationships window and show all the tables. Drag them around so it all makes
sense.

Just take this as an idea. I think it is about right, but maybe not.

CREATE TABLE Countries (
CountryCode CHAR(2) NOT NULL,
CountryName VARCHAR(50) NOT NULL,
CONSTRAINT pk_Countries PRIMARY KEY (CountryCode)
);
CREATE TABLE Zones (
ZoneNumber SMALLINT NOT NULL,
ZoneName VARCHAR(50) NOT NULL,
CONSTRAINT pk_Zones PRIMARY KEY (ZoneNumber) There is no zone name.
);
CREATE TABLE CountryZones (
CountryCode CHAR(2) NOT NULL,
CONSTRAINT fk_Countries_CountryZones
FOREIGN KEY (CountryCode) REFERENCES
Countries (CountryCode),
ZoneNumber SMALLINT NOT NULL,
CONSTRAINT fk_Zones_CountryZones
FOREIGN KEY (ZoneNumber) REFERENCES
Zones (ZoneNumber),
CONSTRAINT pk_CountryZones
PRIMARY KEY (CountryCode, ZoneNumber)
);
Given a country table and a zone table, this seems redundant.
CREATE TABLE Stations (
CallSign VARCHAR(6) NOT NULL,
OperatorName VARCHAR(50),
CountryCode CHAR(2),
ZoneNumber SMALLINT NOT NULL,
CONSTRAINT fk_CountryZones_Stations
FOREIGN KEY (CountryCode, ZoneNumber) REFERENCES
CountryZones (CountryCode, ZoneNumber),
CONSTRAINT pk_Stations PRIMARY KEY (CallSign)
);
If this is for members, then I don't need Name, Country, or Zone.
CREATE TABLE DesignatedGroups (
GroupID AUTOINCREMENT NOT NULL,
GroupName VARCHAR(50) NOT NULL,
CONSTRAINT pk_DesignatedGroups PRIMARY KEY (GroupID)
);
What's this for?
CREATE TABLE DesignedGroupMembers (
GroupID LONG NOT NULL,
CONSTRAINT fk_DesignatedGroups_DesignedGroupMembers
FOREIGN KEY (GroupID) REFERENCES
DesignatedGroups (GroupID),
CallSign VARCHAR(6) NOT NULL,
CONSTRAINT StationsDesignedGroupMembers
FOREIGN KEY (CallSign) REFERENCES
Stations (CallSign),
JoinedDate DATETIME NOT NULL,
CONSTRAINT pk_DesignedGroupMembers
PRIMARY KEY (GroupID, CallSign)
);
And this?
CREATE TABLE GroupContacts (
GroupID LONG NOT NULL,
CallSign_One VARCHAR(6) NOT NULL,
CONSTRAINT fk_DesignedGroupMembers_GroupContacts
FOREIGN KEY (GroupID, CallSign_One) REFERENCES
DesignedGroupMembers (GroupID, CallSign),
CallSign_Two VARCHAR(6) NOT NULL,
CONSTRAINT fk_Stations_GroupContacts
FOREIGN KEY (CallSign_Two) REFERENCES
Stations (CallSign),
ContactDate DATETIME NOT NULL,
DurationMinutes SMALLINT,
CONSTRAINT pk_GroupContacts
PRIMARY KEY (GroupID, CallSign_One,CallSign_Two,ContactDate)
);
Maybe if GroupID is dropped, and zone is added.
 
M

Michael Gramelspacher

Thanks, Michael -
Comments are below the tables they apply to.


I would actually just use Access to create/define the DB.
Given a country table and a zone table, this seems redundant.

If this is for members, then I don't need Name, Country, or Zone.

What's this for?

And this?

Maybe if GroupID is dropped, and zone is added.

All the SQL does is create the tables as shown in the relationships image.
http://www.psci.net/gramelsp/temp/image1.jpg

In your case it would be:
DesignatedGroups = Clubs
DesignatedGroupMembers = ClubMembers
GroupContacts = ClubContacts

You do not want a CountryZones table, so do have one.

It is merely a suggestion, but in the end it is always your call.
 
M

MikeR

Michael said:
All the SQL does is create the tables as shown in the relationships image.
http://www.psci.net/gramelsp/temp/image1.jpg

In your case it would be:
DesignatedGroups = Clubs
DesignatedGroupMembers = ClubMembers
GroupContacts = ClubContacts

You do not want a CountryZones table, so do have one.

It is merely a suggestion, but in the end it is always your call.

And I do appreciate the suggestions, and the time it took to do them!
Happy holidays.
Mike
 
M

MikeR

Stefan, thanks for your time and efforts. You definitely gave me some food for thought.

Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top