• 0

[SQL] Database structure


Question

I?m in the process of re-designing a database at the moment. I?ve spent the last few days on it to make sure that it?s perfect. I?m aiming to have it in 3NF with cascading updates and deletes.

Guess I have a few questions:

  • Most of my tables have primary keys; others are just relationships such as ?enrolments? ? what students are assigned to classes. At the moment this table has two regular keys ?class_id? and ?student_id?? should both of these be primary keys (or unique) or should I just leave the table the way it is?
  • I have not specified any limits for my varchars. Is this bad practice or does it even matter seen that they are ?variable length? characters?
    From what I understand one byte equates to one regular latin character. This will be a multi-lingual application so the tables will need to be UTF-8 character encoded. How does this affect the varchars length?
    Eg: varchar(25) how many UTF-8 characters can this store, will this allow the same amount of characters no matter what language script is used?

Thanks in adva:pe ? hope someone can help :p

Link to comment
https://www.neowin.net/forum/topic/844270-sql-database-structure/
Share on other sites

12 answers to this question

Recommended Posts

  • 0

Just found on oracles website that:

"One Unicode character can be 1 byte, 2 bytes, 3 bytes, or 4 bytes in UTF-8 encoding. Characters from the European scripts are represented in either 1 or 2 bytes. Characters from most Asian scripts are represented in 3 bytes. Supplementary characters are represented in 4 bytes."

So... does this mean that if i want a varchar field to store a maximim of 10 characters - i would have to define the field as varchar(40)?

I'm guessing i'll have to check programmatically whether the user the user has entered more than 10 characters as this would also allow 40 regular ASCII characters.

Correct?

  • 0

no, you'd still set it as varchar(10). In the background each character simply takes up between 1-4 bytes for oracle to store on the hdd/ram, rather than just 1. The limit on the number of characters will be 10.

If you've got a link table, like students >- link -< classes, containing student_id and class_id, both fields will need to be individually set as foreign keys, and the two combined will be set as the primary key for that table.

  • 0
no, you'd still set it as varchar(10). In the background each character simply takes up between 1-4 bytes for oracle to store on the hdd/ram, rather than just 1. The limit on the number of characters will be 10.

So does this apply to MySQL also or is this just a feature unique to oracle databases?

Just looked up MSDN's definition of varchar: "Variable-length non-Unicode character data".

It seems to suggest that I should use nvarchar for storing Unicode character data. I've never heard of nvarchar... does it really matter?

[edit]

Seems that i should be using nvarchar afterall

"The difference between varchar(300) and nvarchar(300) is that the maximum varchar size is 300 single-byte symbols. The definition nvarchar(300) means that it will store up to 300 symbols multibyte encoded, regardless of their code length."

http://social.msdn.microsoft.com/Forums/en...84-d1a4daba4ef2

[/edit]

If you've got a link table, like students >- link -< classes, containing student_id and class_id, both fields will need to be individually set as foreign keys, and the two combined will be set as the primary key for that table.

So... "class_id" and "student_id" are foreign keys of their respective tables and both primary keys of the link table?

Im guessing the same applies for other tables such as a high score table:

student_id - foreign and primary key

game_id - foreign and primary key

score - primary key

date_earned - primary key

btw... thanks for the help, really wanted to build a solid database before starting into the code :p

Edited by Guest
  • 0

Looking at the MySQL reference manual it says that:

Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 255 before MySQL 5.0.3, and 0 to 65,535 in 5.0.3 and later versions

assuming i'm using a version older than 5.0.3 i can only store 255 ASCII / UTF-8 characters - right?

  • 0

If you're using MySQL < v5.0.3 and you want to store more than 255 characters (ASCII/UTF-8, no difference!), you'll need to use a blob/text type column.

MySQL does not have nchar/nvarchar type fields, it only has char and varchar. To support unicode it instead allows you to specify character sets and collations. Otherwise, with other dbms's yes, you'd use nchar/nvarchar.

http://www.dotnetspider.com/forum/176341-I...type-MySql.aspx

  • 0

Yea, ran into that problem today... MySQL kept converting my nvarchars into varchars

CREATE TABLE IF NOT EXISTS `classes` (
`class_ID` INT NOT NULL AUTO_INCREMENT ,
`teacher_ID` INT NOT NULL ,
`class_name` VARCHAR(50) NOT NULL ,
`enrolment_key` VARCHAR(50) NOT NULL ,
`enrolment_lock` VARCHAR(10) NOT NULL DEFAULT 'closed' ,
PRIMARY KEY (`class_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Is this enough then to support unicode then?

  • 0

afaik, yes i believe so!

So... "class_id" and "student_id" are foreign keys of their respective tables and both primary keys of the link table?

Im guessing the same applies for other tables such as a high score table:

student_id - foreign and primary key

game_id - foreign and primary key

score - primary key

date_earned - primary key

Do score and date_earned really need to be part of the primary key for this table? Can students actually earn more than one score per game_id?

  • 0
afaik, yes i believe so!

Good, i can finally get on to some code now :)

Do score and date_earned really need to be part of the primary key for this table? Can students actually earn more than one score per game_id?

Thats be the high score table... it stores the highest score a person got in the table.

If the person beats the game for the first time a record is stored in that table. If they beat that score the next time they play, the record is modified to show the highest score. In this case im guessing all the fields need to be set as the primary key.

  • 0
Thats be the high score table... it stores the highest score a person got in the table.

If the person beats the game for the first time a record is stored in that table. If they beat that score the next time they play, the record is modified to show the highest score. In this case im guessing all the fields need to be set as the primary key.

If you're replacing score and date_earned whenever a higher score is achieved then no, student_id + game_id will be the primary key. This will allow one and only one record per student per game! Adding further columns to the primary key breaks this restriction, and your database will not be fully normalized!

I question the need for this table though. I presume you have another table where you store all of the scores achieved, why not simply query this to get the information you desire rather than duplicating data. If you want to get the high score data from the score table like you currently have in the high score table, sort you records by score, then date, and then group by student_id and game_id (e.g. SELECT * FROM scores ORDER BY score, date_earned GROUP BY student_id, game_id; not sure if this is correct sql, been a little while...).

btw, in reality normalization in database design is often slightly compromised in exchange for simplicity/efficiency/performance/whatever, so don't worry too much if your design isn't fully 3NF!

  • 0

Gah... your right, wasn't thinking about that. game_id and student_id are the only primary keys needed.

This is the only table that scores high scores. Each game will add the highest score a player achieves into this table. No point recording all the scores a player achieves if they are only ever interested in their highest score.

Thanks again.

  • 0

Just one more question...

at the moment i have a student table, this contains their student_id which is a primary key along with their username, password and profile information.

would it be more efficient to split this table into two, one just storing the unique id, username and password while the other table storing their profile info such as real name, dob, bio etc...

student_table

------------------------

student_id

username

password

profile_table

------------------------

forename

surname

date_of_birth

nationality

bio

interests

etc...

I'm just trying to plan in advance... just incase one day this table has millions of entries.

Is this necessary or does the primary key index remove the need for this?

Thanks

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Close, but it is for any application starting, not just during boot time. In fact, it probably will not improve boot time at all because during a boot, the CPU is already boosting, so a pre-boost wouldn't change anything. I agree that it isn't exciting (especially considering every other OS already does it), but it is a good thing, even if they are just playing catch up.
    • Any so called performance increase will be in milliseconds, which nobody will actually notice in real world usage.
    • All it does is use the CPU more efficiently during boot to speed up boot times. That's it. Yawn....
    • It's not a one or the other kind of thing. Software should run efficiently, and the operating system should appropriately manage the CPU clocks. You could have the best most optimized software on earth, and it will still run faster if the CPU does a better job of boosting as needed. All this is doing is pre-boosting the CPU based on user actions, instead of waiting for the normal detection mechanism to kick in. If the OS knows it is about to need more CPU, why shouldn't it use that knowledge? It's the same idea of downshifting before passing someone, instead of just burying your foot into the peddle and waiting for the transmission to figure out what you want to do.
    • Audacity 3.7.8 by Razvan Serea Audacity is a free, open source digital audio editor and recording application. Edit your sounds using cut, copy, and paste features (with unlimited undo functionality), mix tracks, or apply effects to your recordings. The program also has a built-in amplitude-envelope editor, a customizable spectrogram mode, and a frequency-analysis window for audio-analysis applications. Built-in effects include bass boost, wah wah, and noise removal, and the program also supports VST plug-in effects. You can use Audacity to: Record live audio. Record computer playback on any Windows Vista or later machine. Convert tapes and records into digital recordings or CDs. Edit WAV, AIFF, FLAC, MP2, MP3 or Ogg Vorbis sound files. AC3, M4A/M4R (AAC), WMA and other formats supported using optional libraries. Cut, copy, splice or mix sounds together. Numerous effects including change the speed or pitch of a recording. Write your own plug-in effects with Nyquist. And more! See the complete list of features. Audacity 3.7.8 changelog: #10688 Fixed an exception thrown when pasting into a newly-created track (Thanks, David Bailes (@DavidBailes)!) #10870, #10884, #10775, #10629 Fixed tone generation, waveform-scale setting, SetClip Name parameter, and clip-boundary command names for scripting and macros (Thank you, David Bailes (@DavidBailes)!) #11106 Fixed the loading of presets for the Distortion effect (A million thanks, David Bailes (@DavidBailes)!) #10947 Fixed paste into an empty audio track not preserving the source sample rate (Thanks, Juan Gabriel Colonna (@juancolonna)!) #10776 Allowed AltGr modifier in label and clip name editing (Thanks, Davide Peressoni (@DPDmancul)!) #9938 Added options to choose where silence is truncated (start/middle/end) (Thanks, Noah Rosenfield (@nosenfield)!) #9935 Added Podcast 2.0 chapters JSON export for label tracks (Thanks, Noah Rosenfield (@nosenfield)!) #10103 Improve UI on HiDPI displays on Linux/wxGTK (Thanks, Ivan A. Melnikov (@iv-m)!) #10099 Fixed MixerBoard Mute and Solo button display (Thanks, Ivan A. Melnikov (@iv-m)!) #10681 Fixed multichannel FLAC import #10999 Fixed envelope being broken after joining clips Download: Audacity 64-bit | Standalone ~20.0 MB (Open Source) Download: Audacity 32-bit | Standalone Download: Audacity ARM64 | Standalone View: Audacity Home Page | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
  • Recent Achievements

    • One Month Later
      highriskpaym earned a badge
      One Month Later
    • Week One Done
      highriskpaym earned a badge
      Week One Done
    • One Year In
      highriskpaym earned a badge
      One Year In
    • Week One Done
      FBSPL earned a badge
      Week One Done
    • One Year In
      Jim Dugan earned a badge
      One Year In
  • Popular Contributors

    1. 1
      +primortal
      499
    2. 2
      PsYcHoKiLLa
      198
    3. 3
      +Edouard
      155
    4. 4
      Steven P.
      84
    5. 5
      ATLien_0
      71
  • Tell a friend

    Love Neowin? Tell a friend!