เป็นวิธีที่ดีที่สุดในการแทรกชุดข้อมูลขนาดใหญ่ลงในฐานข้อมูล MySQL (หรือฐานข้อมูลทั่วไป)


9

เป็นส่วนหนึ่งของโครงการ PHP ฉันต้องแทรกแถวลงในฐานข้อมูล MySQL เห็นได้ชัดว่าฉันคุ้นเคยกับการทำสิ่งนี้ แต่สิ่งนี้จำเป็นต้องแทรกเข้าไปใน 90 คอลัมน์ในการสืบค้นเดียว ข้อความค้นหาผลลัพธ์น่ากลัวและเสาหิน (โดยเฉพาะการแทรกตัวแปร PHP ของฉันเป็นค่า):

INSERT INTO mytable (column1, colum2, ..., column90) 
VALUES
('value1', 'value2', ..., 'value90')

และฉันกังวลว่าฉันจะไม่ทำอย่างนี้ มันใช้เวลานาน (น่าเบื่อ) ในการพิมพ์ทุกอย่างและการทดสอบการเขียนรหัสทดสอบจะน่าเบื่อเท่า ๆ กัน

มืออาชีพทำงานเกี่ยวกับการเขียนและทดสอบคิวรีเหล่านี้อย่างรวดเร็วได้อย่างไร มีวิธีที่ฉันสามารถเพิ่มความเร็วของกระบวนการหรือไม่


2
ฉันกังวลว่าตารางจะมี 90 คอลัมน์มากกว่าระยะเวลาเล็กน้อยที่ใช้ในการพิมพ์ในชื่อคอลัมน์ (BTW ฉันลากและวางคอลัมน์ทั้งหมดในครั้งเดียวใน SQL Server ไม่มีสถานที่ที่จะทำเช่นเดียวกันใน mySQL หรือ PHP หรือไม่ฉันต้องการดูว่าคุณสามารถพบว่ามันทำให้ชีวิตง่ายขึ้นเพราะไม่มีการพิมพ์ผิด)
HLGEM

1
ฉันรู้ว่า 90 คอลัมน์มีจำนวนมาก แต่แต่ละคอลัมน์เกี่ยวข้องกับเขตข้อมูลเดียวสำหรับเอกสาร PDF ที่ฉันต้องเติมและฉันไม่เห็นจุดในการแตกหักหรือวิธีการที่ฉันจะทำ ขอบคุณสำหรับข้อมูลเกี่ยวกับ SQL Server ฉันไม่แน่ใจว่าคุณหมายถึงการลากและวางคอลัมน์ แต่ฉันจะดู
โจ

1
เขียนคำสั่งเลือกที่แสดงรายการคอลัมน์ทั้งหมดในตารางที่กำหนดและไปจากที่นั่น
JeffO

Jeff O: ฉันก็เคยใช้มันเช่นกันมันอาจเป็นเทคนิคที่ทรงพลังมากถ้าทำถูก คุณควรโพสต์สิ่งนั้นเป็นคำตอบหากคุณสามารถยกตัวอย่างรหัสได้!
FrustratedWithFormsDesigner

คำตอบ:


7

Joe ความคิดเห็นล่าสุดของคุณอธิบายไว้มากมาย ฉันคิดว่าปัญหาที่แท้จริงคือการออกแบบข้อมูล คอลัมน์ใหม่อาจจำเป็นเมื่อมีการเปลี่ยนแปลงรูปแบบเอกสารและในรูปแบบเอกสารประสบการณ์ของฉันมักจะเปลี่ยนบ่อย แทนที่จะเป็นตาราง 90 คอลัมน์ที่มีแถวเดียวต่อรายงานฉันจะเก็บข้อมูลรายงานในตารางที่มีสี่คอลัมน์: report_id, format_id, field_name, field_value แต่ละรายงานจะแสดงด้วย 90 แถวหนึ่งรายการสำหรับแต่ละค่าของฟิลด์ในรายงาน วิธีนี้จะทำให้รหัสของคุณง่ายขึ้นมาก


ขอบคุณสำหรับการตอบกลับของคุณ. เขตข้อมูลทั้งหมด (นอกเหนือจากดัชนี) คือ VARCHARS ดังนั้นมันจึงใช้ได้กับฉัน (และฉันสามารถแปลงค่าอื่น ๆ ได้) ฉันอาจเสียพื้นที่จำนวนมาก แต่เนื่องจากฉันต้องมีขนาดคอลัมน์ field_value ตั้งค่าที่ใหญ่ที่สุด (ประมาณ 256 chars ยาว) ในขณะที่บางฟิลด์ต้องการความยาว 3 เท่านั้นแน่นอนว่ามันจะง่ายกว่าที่จะใช้ และฉันสามารถเข้าใจว่ามันจะเป็นหลักฐานในอนาคตมากขึ้นตามที่คุณอธิบาย
โจ

4
FWIW ระบบฐานข้อมูลส่วนใหญ่ใช้พื้นที่มากเท่าที่จำเป็นในการจัดเก็บข้อมูล ดังนั้นถ้าคุณเก็บเพียง 3 ตัวอักษรในเขตข้อมูล VARCHAR (256) มันจะใช้เวลาเพียง 3 ไบต์ไม่ใช่ 256 ฉันไม่ทราบเกี่ยวกับ MySQL internals มากนัก แต่ฉันจะแปลกใจถ้าพวกเขาอัดฟิลด์ของพวกเขาให้เต็ม ขนาดประกาศ
TMN

@TMN นั่นคือความหมายของ VAR ใน VARCHAR! อักขระความยาวแปรผัน นี่คือฟังก์ชั่น (หรือคำจำกัดความ) ของชนิดข้อมูลไม่ใช่ระบบฐานข้อมูล ไม่ใช่เพราะ a VARCHAR เป็น Variable Length ฐานข้อมูลจำเป็นต้องทราบความยาวสำหรับแต่ละค่าดังนั้นมันจึงเก็บความยาวเป็นเมทาดาทา นั่นหมายถึงการจัดเก็บข้อมูลค่าใช้จ่าย! ดังนั้น VARCHAR (1) ใช้ข้อมูล 3 ไบต์เพราะค่าใช้จ่าย 3 เท่าของ Char (1)!
Morons

2
-1, ฉันไม่เห็นด้วยกับคำตอบนี้ในกรณีนี้คุณจะดีกว่าด้วย 90 คอลัมน์ หากเอนทิตีมี 90 จุดข้อมูลดังนั้นให้เก็บข้อมูลของคุณอย่างมีเหตุผล
Morons

@TMN เพียงชี้แจงจุดของฉันว่า "ดังนั้นถ้าคุณเก็บเฉพาะ 3 ตัวอักษรในเขตข้อมูล VARCHAR (256) จะใช้เวลาเพียง 3 ไบต์" ความจริงก็คือจะใช้เวลา 5 ไบต์ไม่ใช่ 3
Morons

7

โดยทั่วไปวิธีที่เร็วที่สุดในการโหลดชุดข้อมูลขนาดใหญ่ลงในฐานข้อมูล SQL คือการใช้อินเตอร์เฟซการโหลดแบบกลุ่ม เท่าที่ฉันรู้ทุก SQL dbms มีอย่างน้อยหนึ่ง

MySQL docs: การใช้ Bulk Loader

หากฉันต้องเปลี่ยนไฟล์ที่คั่นด้วยแท็บหรือเครื่องหมายจุลภาคเป็นคำสั่ง SQL INSERT ฉันจะใช้ awk เพื่ออ่านไฟล์อินพุตและเขียนไฟล์เอาต์พุต ไม่มีอะไรพิเศษจริงๆเกี่ยวกับ awk; มันเพิ่งจะเป็นภาษาการประมวลผลข้อความที่ฉันรู้จักดี คุณสามารถได้ผลลัพธ์เดียวกันโดยเขียนโค้ดใน Perl, Python, Ruby, Rexx, Lisp และอื่น ๆ


2
การโหลดจำนวนมากเป็นวิธีที่จะดำเนินการหากคุณต้องการแทรกแถวจำนวนมาก แต่ในกรณีนี้เขาเพียงแค่แทรกแถวเดียวที่มีคอลัมน์จำนวนมาก การโหลดจำนวนมากจะไม่ช่วยและอาจต้องเขียนโค้ดมากกว่าวิธีการที่ตรงไปตรงมา
TMN

-1 คำตอบนี้ไม่มีจุดคำถามอย่างสมบูรณ์
Doc Brown

2

หากคุณสามารถรับชื่อคอลัมน์ลงในสเปรดชีต Excel ได้อย่างง่ายดายคุณสามารถเขียนแมโคร Excel เพื่อสร้างรหัสสำหรับคิวรีและคำสั่ง DML ที่หลากหลายจากนั้นเพียงวางค่าลงในคอลัมน์อื่นและคำสั่งแทรก / อัปเดตของคุณจะถูกสร้างขึ้นโดยอัตโนมัติ การพิมพ์ด้วยตนเองเป็นวิธีที่ช้ามากในการทำเช่นนั้นดังนั้นดูว่าคุณสามารถหาลูกเล่นโดยใช้เครื่องมือที่มีอยู่ของคุณได้หรือไม่ โปรแกรมแก้ไขข้อความที่มุ่งเน้นการพัฒนาจำนวนมากยังมีความสามารถในการบันทึกและจัดเก็บมาโครเพื่อให้งานซ้ำซากเช่นนี้เร็วขึ้นและง่ายขึ้น


2

หากคุณมีไฟล์ csv คุณสามารถใช้โหลดข้อมูล INFILE ...เพื่อนำเข้าข้อมูล

หากคุณต้องใช้คำสั่ง 'INSERT' การทำแทรกจำนวนมากจะทำให้กระบวนการรวดเร็วขึ้น แทนที่จะเรียกใช้แบบสอบถาม 'INSERT' สำหรับทุกแถวให้จัดกลุ่มแถวพูด 100 และเรียกใช้แบบสอบถาม บางสิ่งเช่นนี้

INSERT INTO theTable (col1, col2, col3,....., col89, col90) 
VALUES
(val11, val12, val13, ........, val189, val190),
(val21, val22, val23, ........, val289, val290),
.......
......
(val101, val102, val103, ........, va1089, val1090);

2

วิธีที่มีประสิทธิภาพในการเขียนข้อมูลแบบสอบถามแบบหลายคอลัมน์ลงในฐานข้อมูล MySQL คือการแปลงข้อมูลเหล่านี้เป็นรูปแบบ JSON หรือ YAML และแทรกไว้ในหน่วยเดียว มันเปลี่ยน "เขียนแทรกสำหรับตารางที่มี 90 คอลัมน์" เป็น "เขียนแทรกลงในตารางที่มีหนึ่งคอลัมน์"

ในวิธีการนี้ทุกอย่างไม่จำเป็นต้องแบ่งออกเป็นองค์ประกอบฐานและตัวเลขเดียวจะถูกเก็บไว้เพียง 1 คอลัมน์


@gnat: มันนำเสนอโซลูชั่นทางเลือก มันเปลี่ยน "เขียนแทรกสำหรับตารางที่มี 90 คอลัมน์" เป็น "เขียนแทรกลงในตารางที่มีหนึ่งคอลัมน์" รับปัญหาตามที่อธิบายไว้มันเป็นวิธีการแก้ปัญหาที่ถูกต้อง ไม่ใช่ทุกสิ่งที่จะต้องแยกย่อยเป็นส่วนประกอบพื้นฐาน คำตอบที่คล้ายกันอื่น ๆ เท่านั้นที่แนะนำให้ใช้ NoSQL แบบเต็มกำจัดฐานข้อมูล SQL ทั้งหมดซึ่งเกินความจริง คำตอบนี้บอกว่าคุณสามารถใช้วิธีการแบบผสม ทำเพียง 1 คอลัมน์สำหรับข้อมูลชิ้นเดียวนี้ พิจารณาว่าทางเลือกอาจเป็นคอลัมน์ไบนารีและจัดเก็บไฟล์ PDF ทั้งหมด
jmoreno

@gnat: ฉันจะให้โอกาส Noviff ในคำพูดของเขา ...
jmoreno

@ gnat และ jmoreno - ขอบคุณสำหรับความคิดเห็นของคุณ ฉันชอบคำอธิบายที่ชัดเจนของริ้นและฉันก็แก้ไขคำตอบตามคำชี้แจงของเขา
Noviff

0

ด้วย MySQL คุณสามารถใช้ไวยากรณ์ทางเลือกสำหรับinsertคำสั่ง:

insert into table
        set column1 = value1
          , column2 = value2
          , column3 = value3

1
เร็วกว่านี้จริงไหม
Pacerier

@Pacerier ไม่มันไม่เร็วกว่านี้ เพียงอีกไวยากรณ์
Kaspars Foigts

0

สถานการณ์ของคุณดูเหมือนจะเหมาะสมมากสำหรับโซลูชัน NoSQL เนื่องจากรายการแอตทริบิวต์สามารถเปลี่ยนแปลงได้ทุกเมื่อที่การเปลี่ยนแปลงรูปแบบ คุณประเมินตัวเลือกอื่นที่ไม่ใช่ MySQL แล้วหรือยัง? ขุดรอบ DynamoDB / MongoDB / Cassandra - ซึ่งอาจเหมาะสมกว่า


-1

มีวิธีที่มีประสิทธิภาพมากกว่าในการแทรกข้อมูลลงในฐานข้อมูลโดยใช้ php และ mysql เราสามารถใช้คำสั่งโหลดเพื่อแทรกข้อมูล มันแทรกข้อมูลอย่างรวดเร็วอย่างน่าทึ่ง

สำหรับสิ่งนี้สร้างไฟล์ flat (เช่นฉันใช้ไฟล์. csv) กับข้อมูลของคุณโดยใช้fputcsv()ฟังก์ชั่น จากนั้นแทรกข้อมูลโดยใช้คำสั่งโหลด ซินแท็กซ์บางอย่างที่คล้ายกันดังนี้:

LOAD DATA LOCAL INFILE "C:/downloads/local/my_data_file.csv"
INTO TABLE  my_data
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES;

-1

ลองทำสิ่งต่อไปนี้ ทำงานให้ฉัน

ชื่อแบบฟอร์มต้องเท่ากับชื่อคอลัมน์ฐานข้อมูล

รับค่าดังต่อไปนี้:

foreach ($_GET as $formName => $value) {
    $sql = mysql_query("UPDATE table_name SET $formName = '$value' WHERE ID= $id");
}

คุณต้องใส่ ID ก่อนที่จะวนลูป foreach คุณสามารถรับ ID ต่อไปโดยทำ:

SELECT MAX(id) FROM .....

เพิ่ม 1 id และแทรก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.