0

I’m trying to create a web application with a forum and user profile along with other functions. However I’m thinking about how I might implement an ID for each user. The best way I’ve seen other applications do it so far is like Discords, which is something I’d like to emulate in my own app.

Here is a link to Discords Wikipedia page if you're not sure what it is.

In Discords approach every user has an assigned 4 digit number in the form of #5456 for example. There is also a user chosen username that can be always be changed. This username is prepended before the assigned number so the full ID has the form of something like user#7853. See the screenshot below for a real world example:

enter image description here

I like this approach as it allows the user to change their name to a username that is already taken. However there are few things that are confusing me, firstly Discord has way more than 9999 users yet each user has a 4 digit ID. Secondly I’ve seen some users with duplicate numbers, usually that of #0001, which I think is what you get after buying some premium feature.

I have no idea how this works since I assumed the assigned numbers had to be unique. The only way I can think of both of these problems being solved is that the username and number are tied into a single ID, making both the username and number the factors that make the ID unique. But I’m not entirely sure if this is how it works.

If we assume that the latter is true where the both the name and number make up the entire ID, how might I be able to implement that into a MySQL user table using Java Spring JPA and Hibernate? At the moment I have this entity class for a user:

@Entity
public class User
{
    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
    private UserProfile userProfile;

    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
    private UserPosts userPosts;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private long points;
    private String email, username, password;
    private Date dateJoined;

    public User() { }

    // getters and setters
}

I have an ID of type long, but I think this would need to be changed into a new type that can be composed of both a string and a number. So I thought about creating a new ID object that can have both a string and a number.

Would I be able to store an object like this as an ID in a MySQL table and would this be the right approach by creating an ID object? Are my assumptions about how Discords user ID system works correct?

Any insight on the matter would be appreciated.

Thanks.

1 Answer 1

1

As you have already noted, your "reverse engineered" requirements are contradictory:

  • numeric part of user handle is 4 digits
  • more than 10000 users
  • name part can be freely changed

This would allow a user to change his handle to that of another user with the same numeric part, and of course that should not be allowed.

Once you know that your requirements are contradictory, you should stop thinking about how to implement them. It's not possible, no clever indexing scheme will change that.

Instead you will have to first fix the requirements, for example by requiring that no two users may have the same handle at the same time, or that handles may not be reused by other users once they have been used by one. Some further research might be able to find out how Discord does it, but you may just as well define your own rules.

Once you see that the numeric part alone is not enough to identify a user, and that the name part can be changed (with certain restrictions to ensure that no two users have the same handle) it is clear that the information in the handle is not a stable ID. You need a hidden ID (which can be just a plain sequential number) to identify the user in the database. The handle would be stored in the user record to enable looking up the user, and you could store it either as a simple string or store name and numeric parts separately, whatever suits the handle-handling functionality better.

3
  • I think you're quite right in saying I should forget about how Discord do it. As for my own approach, would the hidden id you mentioned be the numeric part that should be unique, and the name part the one that can be the same? That's how the Stack Exchanges seems to work. I even tested it and changed my username to 'test'. I looked up users called test and there were loads, each had their own unique 6 digit number in the user profiles urls along with their identical names of 'test'. That approach seems a lot more simple and reasonable. Commented Jun 25, 2020 at 15:01
  • Another thing I have to ask, is that when you say 'handle' do you mean the unique number and non unqiue name merged together to create the overall ID for the user? Also you said I could store the number and the name as a single string or store them seperatly, would there be any advantages / disadvantages to either approach? Sorry for all the questions but i'm fairly new to programming. And I appreciate your first answer. Commented Jun 25, 2020 at 15:06
  • Regarding the first comment, yes, using the internal ID would be simplest. The name then is only a kind of comment. Regarding the second comment, that's what I meant with "handle", I did not check how Discord calls it. Storing as separate fields is perhaps the easiest approach, then your ID field is fixed and only the name field can ever be changed. Commented Jun 25, 2020 at 15:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.