Question

I am a bit new to SQLite, and I am having a slight dilemma about my database design. I'll explain. Suppose you and your friends use a number of different nicknames on the Internet (can be more than one per person). What we have here is an ID of the person and a list of all nicknames that this person uses. This is a single entry in a large list. The goal here is to store this data by using SQLite in a way the SELECT statement can be used to fetch all entries that contain the specified nickname.

I have thought about creating a table with two columns, first being the ID (primary key) and the other being a TEXT that holds nicknames in a CSV format. However in this example I don't know how to write the select statement to search and match nicknames stored in CSV.

Ideas?

Was it helpful?

Solution

For starters, here is what you have

SELECT Name, Nickname FROM MyTable WHERE Nickname = 'Copper';

But I would strongly suggest having a table for Names, and a table for Nicknames used, such that the Nickname has a reference to Names.

CREATE TABLE Users (
    UserId INTEGER PRIMARY KEY, 
    Name TEXT
    );
CREATE TABLE Nicknames (
    NickNameId INTEGER PRIMARY KEY, 
    UserId INTEGER REFERENCES Users(UserId), 
    NickName Text
    );

You will find this scheme will give you more control to edit entries, remove them, etc.

Query it with either an INNER JOIN:

SELECT Users.Name, NickNames.NickName 
    FROM Users INNER JOIN NickNames ON User.UserId=NickNames.UserId
    WHERE NickNames.NickName = 'Copper';

Or a nested query:

SELECT Users.Name
    FROM Users
    WHERE User.UserId IN (
    SELECT NickNames.UserId 
        FROM NickNames 
        WHERE NickNames.NickName = 'Copper');

The two are equivalent (in this case) to specifying the join with a WHERE clause. It works, but it's poor form (it's not as clear as INNER JOIN):

SELECT Users.Name, NickNames.NickName 
    FROM Users, NickNames 
    WHERE User.UserId = NickNames.UserId
    AND NickNames.NickName = 'Copper';

OTHER TIPS

Why not just have the following tables:

Person (columns: person_id, person_name)

Nickname (columns: nickname_id, nickname)

Person_Nickname (columns: person_id, nickname_id)

Then you create foreign keys from Person to Person_Nickname and from Nickname to Person_Nickname. This allows a given person to have as many nicknames as you like.

Then, to find all persons which match a given nickname, you can write:

SELECT p.person_name
  FROM person.p
     , nickname n
     , person_nickname pn
 WHERE n.nickname = 'nickname of interest'
   AND p.person_id = pn.person_id 
   AND n.nickname_id = pn.nickname_id

You need 2 tables:

  • users
  • nicknames

In table "users" you have id, name, other optional information on the user. In table "nicknames" you have user_id, nickname.

It's a one to many assosiation. Then to obtain a list of all user nicknames you query it like this (using the user id):

SELECT nicknames.nickname FROM nicknames WHERE nicknames.user_id=id

As a less database like implementation you could do this:
use only one table with 2 fields (user, nickname). Then you get a list of all john's nicknames (you could use ids, too) associated with a user with a query like this:

SELECT table.nickname FROM table WHERE table.user="john"

The CSV approach works but you would need to implement your own function to add/remove/parse nicknames, and it would almost certainly be slower that the two implementations I explained.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top