-- Choose appropriate integer types based on range requirementsCREATETABLEuser_analytics(idBIGSERIALPRIMARYKEY,-- 64-bit auto-incrementinguser_idINTEGERNOTNULL,-- 32-bit signed integer (-2B to +2B)session_countSMALLINTDEFAULT0,-- 16-bit signed integer (-32K to +32K)page_viewsINTEGERDEFAULT0,-- 32-bit signed integertotal_timeBIGINTDEFAULT0,-- 64-bit signed integercreated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Use appropriate integer types for different use casesCREATETABLEproducts(idSERIALPRIMARYKEY,-- Auto-incrementing primary keycategory_idSMALLINTNOTNULL,-- Foreign key to categories (limited range)price_centsINTEGERNOTNULL,-- Price in cents (avoid floating point)stock_quantityINTEGERNOTNULL,-- Stock quantityweight_gramsINTEGER,-- Weight in gramscreated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Use BIGINT for high-volume countersCREATETABLEevent_logs(idBIGSERIALPRIMARYKEY,event_idBIGINTNOTNULL,-- High-volume event IDsuser_idBIGINTNOTNULL,-- Large user basetimestampBIGINTNOTNULL,-- Unix timestamp in millisecondsdataJSONB);
-- Use NUMERIC for precise decimal calculationsCREATETABLEfinancial_transactions(idSERIALPRIMARYKEY,amountNUMERIC(10,2)NOTNULL,-- 10 digits total, 2 decimal placescurrencyVARCHAR(3)NOTNULL,exchange_rateNUMERIC(8,6),-- High precision for exchange ratesfee_amountNUMERIC(8,4),-- Fee with 4 decimal placescreated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Use appropriate precision for different use casesCREATETABLEmeasurements(idSERIALPRIMARYKEY,temperatureNUMERIC(5,2),-- Temperature with 2 decimal placeshumidityNUMERIC(5,2),-- Humidity percentagepressureNUMERIC(8,2),-- Atmospheric pressurecoordinatesPOINT,-- Geographic coordinatesrecorded_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Avoid FLOAT/REAL for financial calculations-- Use NUMERIC instead for exact decimal arithmeticCREATETABLEprice_history(idSERIALPRIMARYKEY,product_idINTEGERNOTNULL,priceNUMERIC(10,2)NOTNULL,-- Exact decimal price-- price REAL NOT NULL, -- DON'T use REAL for moneyvalid_fromTIMESTAMPTZNOTNULL,valid_toTIMESTAMPTZ);
-- Use DOUBLE PRECISION for scientific calculationsCREATETABLEsensor_data(idSERIALPRIMARYKEY,sensor_idINTEGERNOTNULL,temperatureDOUBLEPRECISION,-- Scientific temperature readingshumidityDOUBLEPRECISION,-- Humidity measurementspressureDOUBLEPRECISION,-- Atmospheric pressureaccelerationDOUBLEPRECISION,-- 3D acceleration vectorrecorded_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Use REAL for less precise measurements where storage mattersCREATETABLEweather_stations(idSERIALPRIMARYKEY,station_nameVARCHAR(100)NOTNULL,latitudeREAL,-- Approximate coordinateslongitudeREAL,-- Approximate coordinateselevationREAL,-- Elevation in meterstemperatureREAL,-- Temperature readingscreated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);
-- Choose appropriate string types based on length and usageCREATETABLEuser_profiles(idSERIALPRIMARYKEY,usernameVARCHAR(50)UNIQUENOTNULL,-- Fixed max lengthemailVARCHAR(255)UNIQUENOTNULL,-- Email addressesfirst_nameVARCHAR(100),-- Nameslast_nameVARCHAR(100),bioTEXT,-- Variable length textwebsite_urlVARCHAR(500),-- URLsphoneVARCHAR(20),-- Phone numberscreated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Use CHAR for fixed-length stringsCREATETABLEcountry_codes(idSERIALPRIMARYKEY,country_codeCHAR(2)NOTNULL,-- ISO country codes (e.g., 'US', 'CA')country_nameVARCHAR(100)NOTNULL,currency_codeCHAR(3)NOTNULL,-- ISO currency codes (e.g., 'USD', 'EUR')created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Use TEXT for large contentCREATETABLEarticles(idSERIALPRIMARYKEY,titleVARCHAR(200)NOTNULL,contentTEXTNOTNULL,-- Large text contentexcerptTEXT,-- Article excerpttagsTEXT[],-- Array of text tagscreated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);
-- Create functions for text validationCREATEORREPLACEFUNCTIONvalidate_email(emailTEXT)RETURNSBOOLEANAS$$BEGINRETURNemail~*'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$';END;$$LANGUAGEplpgsql;CREATEORREPLACEFUNCTIONvalidate_phone(phoneTEXT)RETURNSBOOLEANAS$$BEGINRETURNphone~'^\+?[1-9]\d{1,14}$';END;$$LANGUAGEplpgsql;-- Use constraints with validation functionsALTERTABLEuser_profilesADDCONSTRAINTusers_email_validCHECK(validate_email(email));ALTERTABLEuser_profilesADDCONSTRAINTusers_phone_validCHECK(phoneISNULLORvalidate_phone(phone));-- Create indexes for text searchCREATEINDEXidx_user_profiles_username_lowerONuser_profiles(LOWER(username));CREATEINDEXidx_user_profiles_email_lowerONuser_profiles(LOWER(email));CREATEINDEXidx_articles_content_ginONarticlesUSINGGIN(to_tsvector('english',content));
-- Use TIMESTAMPTZ for timezone-aware timestampsCREATETABLEevents(idSERIALPRIMARYKEY,event_nameVARCHAR(200)NOTNULL,start_timeTIMESTAMPTZNOTNULL,-- Timezone-aware start timeend_timeTIMESTAMPTZNOTNULL,-- Timezone-aware end timetimezoneVARCHAR(50)DEFAULT'UTC',-- Event timezonecreated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP,updated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Use TIMESTAMP for timezone-naive timestampsCREATETABLEsystem_logs(idSERIALPRIMARYKEY,log_levelVARCHAR(20)NOTNULL,messageTEXTNOTNULL,timestampTIMESTAMPDEFAULTCURRENT_TIMESTAMP,-- Server timezonesourceVARCHAR(100),created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Use DATE for date-only valuesCREATETABLEuser_sessions(idSERIALPRIMARYKEY,user_idINTEGERNOTNULL,session_dateDATENOTNULL,-- Date onlylogin_countINTEGERDEFAULT1,total_durationINTERVAL,-- Duration as intervalcreated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);
-- Create timezone-aware tablesCREATETABLEglobal_events(idSERIALPRIMARYKEY,event_nameVARCHAR(200)NOTNULL,event_timeTIMESTAMPTZNOTNULL,timezoneVARCHAR(50)NOTNULL,durationINTERVAL,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Function to convert timezoneCREATEORREPLACEFUNCTIONconvert_to_timezone(input_timeTIMESTAMPTZ,target_timezoneTEXT)RETURNSTIMESTAMPTZAS$$BEGINRETURNinput_timeATTIMEZONEtarget_timezone;END;$$LANGUAGEplpgsql;-- Query with timezone conversionSELECTevent_name,event_time,event_timeATTIMEZONEtimezoneaslocal_time,EXTRACT(TIMEZONEFROMevent_time)astimezone_offsetFROMglobal_eventsWHEREevent_time>='2024-01-01'::timestamptz;
-- Use BOOLEAN for true/false valuesCREATETABLEuser_settings(idSERIALPRIMARYKEY,user_idINTEGERNOTNULL,email_notificationsBOOLEANDEFAULTTRUE,sms_notificationsBOOLEANDEFAULTFALSE,push_notificationsBOOLEANDEFAULTTRUE,two_factor_enabledBOOLEANDEFAULTFALSE,is_activeBOOLEANDEFAULTTRUE,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Use boolean expressions in queriesSELECTuser_id,CASEWHENemail_notificationsANDsms_notificationsTHEN'Both'WHENemail_notificationsTHEN'Email Only'WHENsms_notificationsTHEN'SMS Only'ELSE'None'ENDasnotification_preferenceFROMuser_settingsWHEREis_active=TRUE;
-- Create enum types for controlled vocabulariesCREATETYPEuser_statusASENUM('active','inactive','suspended','deleted');CREATETYPEorder_statusASENUM('pending','processing','shipped','delivered','cancelled');CREATETYPEpriority_levelASENUM('low','medium','high','critical');-- Use enum types in tablesCREATETABLEusers(idSERIALPRIMARYKEY,usernameVARCHAR(50)UNIQUENOTNULL,emailVARCHAR(255)UNIQUENOTNULL,statususer_statusDEFAULT'active',created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);CREATETABLEorders(idSERIALPRIMARYKEY,user_idINTEGERNOTNULL,statusorder_statusDEFAULT'pending',prioritypriority_levelDEFAULT'medium',total_amountNUMERIC(10,2)NOTNULL,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Query with enum valuesSELECTu.username,u.status,COUNT(o.id)asorder_countFROMusersuLEFTJOINordersoONu.id=o.user_idWHEREu.status='active'GROUPBYu.id,u.username,u.status;
-- Use arrays for multiple valuesCREATETABLEproducts(idSERIALPRIMARYKEY,nameVARCHAR(200)NOTNULL,descriptionTEXT,tagsTEXT[],-- Array of text tagscategoriesINTEGER[],-- Array of category IDsimagesTEXT[],-- Array of image URLsspecificationsJSONB,-- JSON specificationscreated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Insert data with arraysINSERTINTOproducts(name,tags,categories,images)VALUES('Laptop Computer',ARRAY['electronics','computers','portable'],ARRAY[1,5,12],ARRAY['laptop1.jpg','laptop2.jpg']),('Smartphone',ARRAY['electronics','mobile','communication'],ARRAY[1,8,15],ARRAY['phone1.jpg','phone2.jpg','phone3.jpg']);-- Query arraysSELECTname,tags,array_length(tags,1)astag_count,categories,imagesFROMproductsWHERE'electronics'=ANY(tags);-- Use array operatorsSELECTname,tagsFROMproductsWHEREtags&&ARRAY['electronics','mobile'];-- Overlap operatorSELECTname,tagsFROMproductsWHEREtags@>ARRAY['electronics'];-- Contains operator
-- Array manipulation functionsCREATETABLEuser_preferences(idSERIALPRIMARYKEY,user_idINTEGERNOTNULL,favorite_categoriesTEXT[],blocked_usersINTEGER[],notification_channelsTEXT[],created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Add elements to arraysUPDATEuser_preferencesSETfavorite_categories=array_append(favorite_categories,'technology')WHEREuser_id=1;-- Remove elements from arraysUPDATEuser_preferencesSETfavorite_categories=array_remove(favorite_categories,'sports')WHEREuser_id=1;-- Query array functionsSELECTuser_id,favorite_categories,array_length(favorite_categories,1)ascategory_count,array_to_string(favorite_categories,', ')ascategories_stringFROMuser_preferencesWHERE'technology'=ANY(favorite_categories);
-- Create JSONB schema validationCREATEORREPLACEFUNCTIONvalidate_user_profile(profile_dataJSONB)RETURNSBOOLEANAS$$BEGIN-- Check required fieldsIFNOT(profile_data?'name'ANDprofile_data?'age')THENRETURNFALSE;ENDIF;-- Validate age is numericIFNOT(profile_data->>'age'~'^\d+$')THENRETURNFALSE;ENDIF;-- Validate age rangeIF(profile_data->>'age')::integer<0OR(profile_data->>'age')::integer>150THENRETURNFALSE;ENDIF;RETURNTRUE;END;$$LANGUAGEplpgsql;-- Add constraint for JSONB validationALTERTABLEuser_profilesADDCONSTRAINTuser_profiles_data_validCHECK(validate_user_profile(profile_data));
-- Enable UUID extensionCREATEEXTENSIONIFNOTEXISTS"uuid-ossp";-- Use UUID for distributed systemsCREATETABLEdistributed_entities(idUUIDPRIMARYKEYDEFAULTuuid_generate_v4(),entity_typeVARCHAR(50)NOTNULL,dataJSONBNOTNULL,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Use UUID for external referencesCREATETABLEexternal_integrations(idSERIALPRIMARYKEY,external_idUUIDNOTNULLUNIQUE,integration_typeVARCHAR(50)NOTNULL,statusVARCHAR(20)DEFAULT'active',created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Generate UUIDsSELECTuuid_generate_v4()asnew_uuid;SELECTuuid_generate_v1()astime_based_uuid;SELECTuuid_generate_v1mc()asmac_based_uuid;
-- Use network types for IP addressesCREATETABLEaccess_logs(idSERIALPRIMARYKEY,user_idINTEGER,ip_addressINETNOTNULL,user_agentTEXT,request_pathVARCHAR(500),response_codeINTEGER,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Insert network dataINSERTINTOaccess_logs(user_id,ip_address,user_agent,request_path,response_code)VALUES(1,'192.168.1.100','Mozilla/5.0...','/api/users',200),(2,'10.0.0.50','Chrome/91.0...','/api/orders',201),(NULL,'203.0.113.1','Bot/1.0','/robots.txt',404);-- Query network dataSELECTuser_id,ip_address,CASEWHENip_address<<'192.168.0.0/16'THEN'Private'WHENip_address<<'10.0.0.0/8'THEN'Private'WHENip_address<<'172.16.0.0/12'THEN'Private'ELSE'Public'ENDasnetwork_typeFROMaccess_logsWHEREcreated_at>=CURRENT_DATE;
-- Create composite typesCREATETYPEaddressAS(streetVARCHAR(100),cityVARCHAR(50),stateVARCHAR(50),zip_codeVARCHAR(20),countryVARCHAR(50));CREATETYPEcontact_infoAS(emailVARCHAR(255),phoneVARCHAR(20),addressaddress);-- Use composite types in tablesCREATETABLEcustomers(idSERIALPRIMARYKEY,nameVARCHAR(100)NOTNULL,contactcontact_infoNOTNULL,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Insert composite type dataINSERTINTOcustomers(name,contact)VALUES('John Doe',ROW('john@example.com','+1-555-0123',ROW('123 Main St','New York','NY','10001','USA'))),('Jane Smith',ROW('jane@example.com','+1-555-0456',ROW('456 Oak Ave','San Francisco','CA','94102','USA')));-- Query composite typesSELECTname,(contact).email,(contact).phone,(contact).address.street,(contact).address.cityFROMcustomers;
-- Create type conversion functionsCREATEORREPLACEFUNCTIONconvert_temperature(valueNUMERIC,from_unitVARCHAR(10),to_unitVARCHAR(10))RETURNSNUMERICAS$$BEGIN-- Convert to Celsius firstIFfrom_unit='fahrenheit'THENvalue:=(value-32)*5/9;ELSIFfrom_unit='kelvin'THENvalue:=value-273.15;ENDIF;-- Convert from Celsius to target unitIFto_unit='fahrenheit'THENRETURN(value*9/5)+32;ELSIFto_unit='kelvin'THENRETURNvalue+273.15;ELSERETURNvalue;-- CelsiusENDIF;END;$$LANGUAGEplpgsql;-- Use type conversionSELECTconvert_temperature(32,'fahrenheit','celsius')ascelsius,convert_temperature(0,'celsius','fahrenheit')asfahrenheit,convert_temperature(273.15,'kelvin','celsius')ascelsius_from_kelvin;
# performance/type_performance.pyimportpsycopg2importtimeimportjsonfromtypingimportDict,List,AnyclassDataTypePerformanceAnalyzer:def__init__(self,connection_params):self.conn_params=connection_paramsdefanalyze_type_performance(self)->Dict[str,Any]:"""Analyze performance of different data types."""conn=psycopg2.connect(**self.conn_params)try:withconn.cursor()ascur:# Test integer typesinteger_performance=self.test_integer_types(cur)# Test string typesstring_performance=self.test_string_types(cur)# Test JSONB vs JSONjson_performance=self.test_json_types(cur)return{'integer_performance':integer_performance,'string_performance':string_performance,'json_performance':json_performance,'analysis_timestamp':'2024-01-15T10:30:00Z'}exceptExceptionase:print(f"Error analyzing type performance: {e}")return{}finally:conn.close()deftest_integer_types(self,cursor)->Dict[str,Any]:"""Test performance of different integer types."""# Create test tablescursor.execute(""" CREATE TEMP TABLE test_integers ( id SERIAL PRIMARY KEY, smallint_col SMALLINT, integer_col INTEGER, bigint_col BIGINT ) """)# Insert test datacursor.execute(""" INSERT INTO test_integers (smallint_col, integer_col, bigint_col) SELECT (random() * 32767)::SMALLINT, (random() * 2147483647)::INTEGER, (random() * 9223372036854775807)::BIGINT FROM generate_series(1, 10000) """)# Test query performancestart_time=time.time()cursor.execute("SELECT COUNT(*) FROM test_integers WHERE smallint_col > 1000")smallint_time=time.time()-start_timestart_time=time.time()cursor.execute("SELECT COUNT(*) FROM test_integers WHERE integer_col > 1000000")integer_time=time.time()-start_timestart_time=time.time()cursor.execute("SELECT COUNT(*) FROM test_integers WHERE bigint_col > 1000000000")bigint_time=time.time()-start_timereturn{'smallint_time':smallint_time,'integer_time':integer_time,'bigint_time':bigint_time}deftest_string_types(self,cursor)->Dict[str,Any]:"""Test performance of different string types."""# Create test tablescursor.execute(""" CREATE TEMP TABLE test_strings ( id SERIAL PRIMARY KEY, varchar_col VARCHAR(100), text_col TEXT, char_col CHAR(10) ) """)# Insert test datacursor.execute(""" INSERT INTO test_strings (varchar_col, text_col, char_col) SELECT 'test_string_' || generate_series, 'long_text_content_' || generate_series, 'char' || generate_series FROM generate_series(1, 10000) """)# Test query performancestart_time=time.time()cursor.execute("SELECT COUNT(*) FROM test_strings WHERE varchar_col LIKE 'test_string_%'")varchar_time=time.time()-start_timestart_time=time.time()cursor.execute("SELECT COUNT(*) FROM test_strings WHERE text_col LIKE 'long_text_content_%'")text_time=time.time()-start_timestart_time=time.time()cursor.execute("SELECT COUNT(*) FROM test_strings WHERE char_col LIKE 'char%'")char_time=time.time()-start_timereturn{'varchar_time':varchar_time,'text_time':text_time,'char_time':char_time}deftest_json_types(self,cursor)->Dict[str,Any]:"""Test performance of JSON vs JSONB."""# Create test tablescursor.execute(""" CREATE TEMP TABLE test_json ( id SERIAL PRIMARY KEY, json_col JSON, jsonb_col JSONB ) """)# Insert test datacursor.execute(""" INSERT INTO test_json (json_col, jsonb_col) SELECT '{"id": ' || generate_series || ', "name": "test_' || generate_series || '", "value": ' || (random() * 1000)::INTEGER || '}', '{"id": ' || generate_series || ', "name": "test_' || generate_series || '", "value": ' || (random() * 1000)::INTEGER || '}'::JSONB FROM generate_series(1, 10000) """)# Test query performancestart_time=time.time()cursor.execute("SELECT COUNT(*) FROM test_json WHERE json_col ->> 'name' LIKE 'test_%'")json_time=time.time()-start_timestart_time=time.time()cursor.execute("SELECT COUNT(*) FROM test_json WHERE jsonb_col ->> 'name' LIKE 'test_%'")jsonb_time=time.time()-start_timereturn{'json_time':json_time,'jsonb_time':jsonb_time,'jsonb_advantage':(json_time-jsonb_time)/json_time*100}# Usageif__name__=="__main__":analyzer=DataTypePerformanceAnalyzer({'host':'localhost','database':'production','user':'analyzer_user','password':'analyzer_password'})results=analyzer.analyze_type_performance()print(json.dumps(results,indent=2))
# Complete PostgreSQL data types setupdefsetup_postgresql_data_types():# 1. Numeric types# 2. Character and text types# 3. Date and time types# 4. Boolean and enum types# 5. Array types# 6. JSON and JSONB types# 7. UUID and network types# 8. Custom types and performance optimizationprint("PostgreSQL data types setup complete!")