block_lists: * id (numeric, auto_increment) * name * more? (I dunno what your "level 1" column is supposed to do.) blocks: * id * username * level * block_list_id * added_by admins: * id * username * more? subscribers: * id * username * more? (You probably want to keep these as separate tables, as it's likely you'll want to track additional stuff for admins that aren't relevant for subscribers, and maybe vice versa.) admin_to_block_list: * id * admin_id * block_list_id subscriber_to_block_list: * id * subscriber_id * block_list_id Sprinkle created_on and updated_on columns liberally; basically every table can use them. Use TIMESTAMP type, and SQL has some column attribute that auto-sets a timestamp on creation or on update. Make sure to classify your ID columns as PRIMARY KEY, and the *_id columns as FOREIGN KEY, and set up UNIQUE constraints where prudent (like on username fields). Set up INDEXes on the columns you'll use in JOINs a lot; particularly "id" on block_lists and blocks (Some people prefer to just, for example, use username as a primary key, but I prefer the symmetry of my row ids *always* being integers; it makes it easier to reason about. If I add a new table that links to something else, for example, I don't have to remember that it uses a VARCHAR primary key or whatever, they're all ints. Also, things become un-unique remarkably often; loosening a UNIQUE constraint is easier than changing foreign keys in all tables that link to it. And sometimes you're only unique when considering several keys together, like a github username+repo combo; having to use *two* columns just to link to a table is obnoxious and annoying. Synthetic primary keys 100% of the time, imo.) block_lists: | id | name | | 1 | misogyny | admins: | id | username | | 1 | @cat | subscribers: | id | username | | 1 | @dog | admin_to_block_list: | id | admin_id | block_list_id | | 1 | 1 | 1 | subscriber_to_block_list: | id | subscriber_id | block_list_id | | 1 | 1 | 1 | blocks: | id | username | block_list_id | added_by | level | | 1 | @mensrights | 1 | 1 | 1 | (If you want to store metadata about blocked people too, give them their own table, and change blocks:username to blocks:blockee_id.)