You are asked to design a simplified SQL engine. The engine should be able to create tables, insert rows, delete rows, and select rows based on simple conditions.
Implement the SQL
class:
SQL()
: Initializes the SQL engine. All tables are initially empty.void createTable(string tableName, vector<string> columns)
: Creates a new table named tableName
with the given columns
. All columns store integer values.void insertRow(string tableName, vector<string> row)
: Inserts a new row into the specified tableName
. The values are provided as a vector of strings. The number of values will match the number of columns, and the values are valid integer strings.void deleteRows(string tableName, string whereColumn, string whereValue)
: Deletes all rows from tableName
where the value in the whereColumn
is equal to whereValue
. You can assume whereColumn
exists and whereValue
is a valid integer string.vector<vector<string>> selectRows(string tableName, vector<string> columns, string whereColumn, string whereValue)
: Selects and returns a list of rows from tableName
. Only rows where the value in whereColumn
is equal to whereValue
should be included. The returned rows should only contain the columns specified in the columns
vector, in the same order.Example 1:
SQL sql = new SQL();
sql.createTable("Employees", {"employee_id", "name", "salary"});
sql.insertRow("Employees", {"1", "Alice", "100000"});
sql.insertRow("Employees", {"2", "Bob", "90000"});
sql.insertRow("Employees", {"3", "Charlie", "80000"});
sql.deleteRows("Employees", "employee_id", "3");
sql.selectRows("Employees", {"name", "salary"}, "salary", "100000");
// returns [["Alice", "100000"]]
sql.createTable("Projects", {"project_id", "project_name"});
sql.insertRow("Projects", {"101", "Alpha"});
sql.insertRow("Projects", {"102", "Beta"});
sql.deleteRows("Projects", "project_id", "101");
sql.selectRows("Projects", {"project_name"}, "project_name", "Beta");
// returns [["Beta"]]
Constraints:
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for designing SQL involves exploring every conceivable table structure and query construction. We essentially try out every single possible database design, evaluate it, and compare it against our requirements. It's like testing every lock to find the right key.
Here's how the algorithm would work step-by-step:
def design_sql_brute_force(requirements):
best_design = None
best_query = None
best_performance = float('inf')
# Consider all possible table structures
possible_table_structures = generate_table_structures()
for table_structure in possible_table_structures:
# Define how the tables relate to each other
table_relationships = generate_table_relationships(table_structure)
for relationship in table_relationships:
# Imagine all the queries
possible_queries = generate_possible_queries(table_structure, relationship, requirements)
for query in possible_queries:
# Evaluate if the query fulfills the requirements
results = execute_query(table_structure, relationship, query)
# Check if the results are acceptable
if check_results(results, requirements):
# Calculate performance of the query
performance = calculate_performance(query, table_structure)
# Keep track of the best design
if performance < best_performance:
best_performance = performance
best_design = table_structure
best_query = query
return best_design, best_query
def generate_table_structures():
# Placeholder function
# Returns a list of possible table structures
return [{"table1": ["col1", "col2"], "table2": ["col3", "col4"]} ]
def generate_table_relationships(table_structure):
# Placeholder function
# Returns a list of possible relationships between tables
return [{"table1": "col1", "table2": "col3"}]
def generate_possible_queries(table_structure, relationship, requirements):
# Placeholder function
# Returns a list of possible queries
return ["SELECT * FROM table1", "SELECT col1 FROM table1"]
def execute_query(table_structure, relationship, query):
# Placeholder function
# Execute query against the table structure and relationship
return [{"col1": "value1", "col2": "value2"}]
def check_results(results, requirements):
# Placeholder function
# Check the results against the requirements
return True
def calculate_performance(query, table_structure):
# Placeholder function
# Return the performance of the query, such as time it took
return 1.0
# The following are example drivers for the function above.
# Define requirements
requirements = {"data_needed": ["col1", "col2"]}
# Consider all possible table structures
# Find the best design
best_table_design, best_sql_query = design_sql_brute_force(requirements)
# Print best table design and best SQL query
print(f'Best Table Design:
{best_table_design}')
print(f'Best SQL Query:
{best_sql_query}')
Designing a database effectively involves understanding the relationships between different pieces of information. The optimal approach centers around breaking down complex data into smaller, manageable parts and defining clear connections between them.
Here's how the algorithm would work step-by-step:
class SQLDesign:
def __init__(self):
pass
def design_database(self):
# Define tables as dictionaries.
tables = {}
# Create the customers table.
tables['customers'] = {
'customer_id': 'INT PRIMARY KEY',
'customer_name': 'VARCHAR(255)',
'customer_email': 'VARCHAR(255)'
}
# Create the orders table.
tables['orders'] = {
'order_id': 'INT PRIMARY KEY',
'customer_id': 'INT',
'order_date': 'DATE',
'total_amount': 'DECIMAL(10, 2)'
}
# Establish foreign key relationship.
# Orders table relates to customers table using customer_id.
tables['orders']['customer_id'] = 'INT FOREIGN KEY REFERENCES customers(customer_id)'
tables['products'] = {
'product_id': 'INT PRIMARY KEY',
'product_name': 'VARCHAR(255)',
'product_description': 'TEXT',
'product_price': 'DECIMAL(10, 2)'
}
tables['order_items'] = {
'order_item_id': 'INT PRIMARY KEY',
'order_id': 'INT',
'product_id': 'INT',
'quantity': 'INT',
'item_price': 'DECIMAL(10, 2)'
}
# Establish foreign key relationships.
# Order items relate to orders and products tables.
tables['order_items']['order_id'] = 'INT FOREIGN KEY REFERENCES orders(order_id)'
# Products need to be linked for item details
tables['order_items']['product_id'] = 'INT FOREIGN KEY REFERENCES products(product_id)'
# Returns the data model as a dictionary.
return tables
Case | How to Handle |
---|---|
CREATE TABLE with duplicate column names | Reject the CREATE TABLE statement if duplicate column names are detected. |
INSERT INTO a table that doesn't exist | Return an error indicating the table does not exist. |
INSERT INTO with incorrect number of values (too few or too many) | Return an error if the number of provided values doesn't match the table schema. |
SELECT * FROM non-existent table | Return an error indicating that the table does not exist. |
WHERE clause with invalid column name | Return an error if the column specified in the WHERE clause does not exist in the table. |
WHERE clause with mismatched data types for comparison | Return an error if data types used in the comparison within the WHERE clause are incompatible. |
Large number of rows in a table causing memory issues | Consider implementing pagination or limiting the size of results returned by SELECT. |
Complex WHERE clauses with nested AND/OR operators and precedence | Implement a proper parser to handle operator precedence and ensure correct evaluation of the WHERE clause conditions. |