hmac - mengapa tidak hmac untuk penyimpanan kata sandi?
<p><strong> nota bene: </strong> saya sadar bahwa <a href="http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html">jawaban yang baik</a> untuk mengamankan penyimpanan kata sandi adalah  <a href="http://www.tarsnap.com/scrypt.html">scrypt</a> atau <a href="http://codahale.com/how-to-safely-store-a-password/">bcrypt</a> . pertanyaan ini bukan untuk implementasi dalam perangkat lunak aktual, ini untuk pemahaman saya sendiri.</p><p>katakanlah joe programmer ditugaskan dengan <strong> dengan aman menyimpan kata sandi pengguna akhir </strong> dalam database untuk aplikasi web; atau menyimpan kata sandi pada disk untuk login ke perangkat lunak. dia kemungkinan besar akan:</p><ol> <li>dapatkan <code>$password</code> dari pengguna akhir.</li> <li>buat <code>$nonce</code> sebagai nilai acak sekitar 64 atau 128 bit.</li> <li>buat <code>$hash = sha256($nonce$password)</code> dan simpan <code>$nonce</code> bersama dengan <code>$hash</code> dalam database.</li> </ol><p><strong> pertanyaan satu: </strong></p><p>mengapa hal berikut tidak jauh lebih baik daripada yang di atas?</p><ol> <li>buat <code>$long\_string</code> sekali dan hanya sekali. simpan ini sebagai konstanta dalam kode aplikasi. <code>$long\_string</code> bisa f.x. menjadi 2 kilobyte karakter acak.</li> <li>dapatkan <code>$password</code> dari pengguna akhir.</li> <li>buat <code>$mac = hmac-sha256($long\_string)[$password]</code> (mis. buat mac menggunakan kata sandi pengguna akhir sebagai kunci) dan simpan <code>$mac</code> ini di basis data.</li> </ol><p><strong> saya akan membayangkan hmac memiliki manfaat berikut? </strong></p><ul> <li>tabrakan lebih jarang?</li> <li>ini komputasi agak lebih mahal daripada hashing biasa? (tapi tentu saja tidak di dekat scrypt.)</li> <li>agar berhasil dengan serangan brute-force dalam waktu yang wajar, dan penyerang perlu mendapatkan akses ke dua hal: <em> 1)</em> database, di mana <code>$mac</code> disimpan, dan <em> 2)</em> kode aplikasi, di mana aslinya <code>$long\_string</code> disimpan. itu lebih baik daripada fungsi hash, di mana penyerang hanya perlu akses ke database?</li> </ul><p>tapi tetap saja, <strong> sepertinya tidak ada yang menyarankan menggunakan hmac, jadi saya pasti salah paham sesuatu? </strong></p><p><strong> pertanyaan dua: </strong></p><p>apa implikasi dari menambahkan nilai garam <code>$nonce</code>?</p><ol> <li>buat <code>$long\_string</code> sekali dan hanya sekali. simpan ini sebagai konstanta dalam kode aplikasi.</li> <li>dapatkan <code>$password</code> dari pengguna akhir.</li> <li>buat <code>$nonce</code> sebagai nilai acak sekitar 128 bit.</li> <li>buat <code>$mac = hmac-sha256($long\_string)[$nonce$password]</code> dan simpan <code>$nonce</code> dan <code>$mac</code> dalam database.</li> </ol>
<p>intinya adalah untuk mencegah pembagian biaya serangan: jika seorang penyerang ingin menyerang dua kata sandi, maka itu harus dua kali lebih mahal daripada menyerang satu kata sandi.</p><p>dengan proposal anda ("pertanyaan 1"), dua pengguna dengan kata sandi yang sama akan menggunakan mac yang sama. jika penyerang memiliki akses baca ke basis data anda, ia dapat "mencoba" kata sandi (dengan menghitung ulang mac) dan mencari basis data untuk kecocokan. dia kemudian dapat menyerang <em>semua</em> kata sandi secara paralel, untuk biaya serangan satu. jika <code>long\_string</code> anda adalah sebuah konstanta hardcoded dalam kode sumber aplikasi, maka semua instal aplikasi yang terinstal membagikan konstanta ini, dan menjadi bermanfaat (bagi penyerang) untuk membuat kamus besar pasangan kata sandi ke mac , juga dikenal sebagai "a rainbow table".</p><p>dengan nonce ("pertanyaan 2") anda, anda menghindari pembagian biaya. nonce biasanya dikenal sebagai "garam". <code>long\_string</code> anda dan penggunaan hmac tidak membeli anda banyak di sini (dan anda tidak menggunakan hmac untuk apa itu dirancang, omong-omong, sehingga anda berada pada fondasi yang goyah, berbicara secara kriptografis). menggunakan garam adalah ide yang sangat bagus (well, <em>tidak</em> menggunakan garam adalah ide yang sangat buruk, setidaknya) tetapi hanya melakukan setengah dari pekerjaan. anda juga harus memiliki prosedur hashing <em>lambat</em>. intinya di sini adalah bahwa garam mencegah pembagian biaya, tetapi tidak mencegah menyerang satu kata sandi. menyerang kata sandi berarti mencoba kemungkinan kata sandi sampai satu yang cocok (itulah "serangan kamus"), dan, mengingat imajinasi rata-rata pengguna manusia, serangan kamus cenderung bekerja: orang hanya <em>cinta</em> menggunakan kata sandi yang dapat tebak. solusinya adalah dengan menggunakan proses hashing yang secara inheren lambat, biasanya dengan mengulangi fungsi hash beberapa ribu kali. idenya adalah untuk membuat verifikasi kata sandi lebih mahal: membuat pengguna menunggu 1ms bukannya 1μs bukanlah kesulitan (pengguna tidak akan menyadarinya), tetapi juga akan membuat serangan kamus 1000 kali lebih mahal. <code>long\_string</code> anda <em>boleh</em> digunakan untuk itu, asalkan itu sangat panjang (bukan 2 kilobyte, lebih dari 20 megabita).</p><p>hmac <em>boleh</em> digunakan sebagai ganti fungsi hash mentah untuk memperkuat sistem verifikasi kata sandi, tetapi dalam pengaturan yang berbeda. dengan sistem yang memeriksa kata sandi dengan garam dan fungsi hash yang diulang, anda dapat mengganti fungsi hash dengan hmac, menggunakan kunci rahasia <em> k </em>. ini mencegah serangan kamus offline selama anda dapat menyimpan <em> k </em> rahasia. menjaga kerahasiaan nilai tidak mudah, tetapi masih lebih mudah untuk menjaga 128-bit <em> k </em> rahasia daripada database lengkap.</p>
<p>randomart dimaksudkan sebagai cara yang lebih mudah bagi manusia untuk memvalidasi kunci.</p><p>validasi biasanya dilakukan dengan perbandingan string yang tidak berarti (yaitu representasi heksadesimal dari sidik jari kunci), yang manusia cukup lambat dan tidak akurat dalam membandingkan. randomart menggantikan ini dengan gambar terstruktur yang lebih cepat dan lebih mudah untuk dibandingkan.</p><p>makalah ini <a href="http://www.ece.cmu.edu/~adrian/projects/validation/validation.pdf">"hash visualisasi: teknik baru untuk meningkatkan keamanan dunia nyata", perrig a. dan song d., 1999, workshop internasional tentang teknik kriptografi dan e-commerce (cryptec '99) "</a> menjelaskan beberapa teknik dan kelebihan.</p> <p>saya bisa menjalankan ini dengan menggunakan kombinasi petunjuk doublecommand dan jtbandes dari <a href="https://superuser.com/questions/26954/how-can-i-remap-ctrl-h-in-mac-os-x/28035#28035">di sini</a> . pertama periksa tombol fungsi bertindak sebagai kotak kunci kontrol dalam perintah ganda. kemudian simpan file ~/library/keybindings/defaultkeybinding.dict dengan konten</p><pre><code>{"^c" = "copy:";} {"^v" = "paste:";} {"^x" = "cut:";} </code></pre><p>setelah anda keluar dan masuk kembali, anda harus dapat menggunakan fn-c untuk menyalin, dll. ada beberapa kelemahan dari pendekatan ini. anda harus mendefinisikan secara eksplisit setiap perintah yang ingin anda gunakan fn untuk dan pemetaan untuk mengontrol dan kemudian fn benar-benar hacky. sayangnya saya tidak bisa membuatnya bekerja dengan cara lain. pada awalnya saya pikir anda mungkin dapat memilih kotak centang "tombol perintah bertindak sebagai kunci kontrol" dan "tombol fn bertindak sebagai tombol kontrol" tetapi itu sepertinya tidak berhasil. ditto untuk mengubah ke kontrol dengan metode alex di atas. saya juga tidak dapat menemukan pengubah untuk menetapkan perintah ke fn, dan dokumentasi apple tampaknya menunjukkan bahwa itu dilakukan pada tingkat yang lebih rendah daripada akses pengikat tombol. jika seseorang tahu cara yang lebih baik untuk melakukan ini, saya akan senang melihatnya.</p> <p>arsitektur innodb menuntut penggunaan empat tipe dasar halaman info</p><ul> <li>halaman data tabel</li> <li>halaman indeks tabel</li> <li>tabel metadata</li> <li> <a href="http://en.wikipedia.org/wiki/multiversion\_concurrency\_control"><strong> [~ # ~] mvcc [~ # ~] </strong></a> data (untuk mendukung isolasi transaksi dan <a href="http://en.wikipedia.org/wiki/acid"><strong> kepatuhan acid </strong></a> ) <ul> <li>segmen kembalikan</li> <li>batalkan spasi</li> <li>double write buffer (penulisan latar belakang untuk mencegah ketergantungan pada caching os)</li> <li>masukkan buffer (mengelola perubahan pada indeks sekunder yang tidak unik)</li> </ul> </li> </ul><p> <a href="http://www.scribd.com/doc/31337494/xtradb-innodb-internals-in-drawing"><strong> <em> lihat representasi pictorial dari ibdata1</em> </strong></a> </p><p>secara default, <a href="http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar\_innodb\_file\_per\_table">innodb\_file\_per\_table</a> dinonaktifkan. ini menyebabkan keempat jenis halaman info mendaratkan satu file bernama ibdata1. banyak orang mencoba menyebar data dengan membuat banyak file ibdata. ini dapat menyebabkan fragmentasi data dan halaman indeks.</p><p>inilah sebabnya saya sering <a href="https://stackoverflow.com/a/4056261/491757">merekomendasikan untuk membersihkan infrastruktur innodb, menggunakan file ibdata1 default dan tidak lebih</a> .</p><p>menyalin sangat berbahaya karena infrastruktur di mana innodb bekerja. ada dua infrastruktur dasar</p><ul> <li>innodb\_file\_per\_table dinonaktifkan</li> <li>innodb\_file\_per\_table diaktifkan</li> </ul><h1>innodb ( <a href="http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar\_innodb\_file\_per\_table">innodb\_file\_per\_table</a> dinonaktifkan)</h1><p>dengan <a href="http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar\_innodb\_file\_per\_table">innodb\_file\_per\_table</a> dinonaktifkan, semua jenis info innodb ini tinggal di dalam ibdata1. satu-satunya manifestasi dari setiap tabel innodb di luar ibdata1 adalah file .frm dari tabel innodb. menyalin semua data innodb sekaligus membutuhkan menyalin semua/var/lib/mysql.</p><p>menyalin tabel innodb individu sama sekali tidak mungkin. anda harus membuang mysql untuk mengekstrak dump tabel sebagai representasi logis dari data dan definisi indeks yang sesuai. anda kemudian akan memuat dump itu ke database lain di server yang sama atau server lain.</p><h1>innodb ( <a href="http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar\_innodb\_file\_per\_table">innodb\_file\_per\_table</a> diaktifkan)</h1><p>dengan <a href="http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar\_innodb\_file\_per\_table">innodb\_file\_per\_table</a> diaktifkan, data tabel dan indeksnya tinggal di folder database di sebelah file .frm. misalnya, untuk tabel db1.mytable, manifestasi dari tabel innodb di luar ibdata1 adalah:</p><ul> <li><code>/var/lib/mysql/db1/mytable.frm</code></li> <li><code>/var/lib/mysql/db1/mytable.ibd</code></li> </ul><h1>tablespace sistem <code>ibdata1</code></h1><p>semua metadata untuk db1.mytable masih berada di ibdata1 dan <em> sama sekali tidak ada jalan lain</em>. redo log dan data mvcc juga masih hidup dengan ibdata1.</p><p>ketika datang ke tabel fragmentasi, inilah yang terjadi pada ibdata1:</p><ul> <li><strong> <a href="http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar\_innodb\_file\_per\_table">innodb\_file\_per\_table</a> diaktifkan </strong>: anda dapat mengecilkan db1.mytables dengan <code>alter table db1.mytable engine=innodb;</code> atau <code>optimize table db1.mytable;</code>. ini menghasilkan /var/lib/mysql/db1/mytable.ibd secara fisik lebih kecil tanpa fragmentasi.</li> <li><strong> <a href="http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar\_innodb\_file\_per\_table">innodb\_file\_per\_table</a> dinonaktifkan </strong>: anda tidak dapat mengecilkan db1.mytables dengan <code>alter table db1.mytable engine=innodb;</code> atau <code>optimize table db1.mytable;</code> karena berada dengan ibdata1. menjalankan perintah mana pun sebenarnya, membuat tabel berdekatan dan lebih cepat untuk membaca dan menulis. sayangnya, itu terjadi pada akhir ibdata1. ini membuat ibdata1 tumbuh dengan cepat. <a href="https://stackoverflow.com/a/4056261/491757">ini sepenuhnya dibahas di pos pembersihan innodb saya</a> .</li> </ul><h1>peringatan (atau bahaya sebagai <a href="http://www.youtube.com/watch?v=rg0ochx16dg&amp;feature=related">robot akan mengatakan dalam lost in space</a> )</h1><p>jika anda berpikir untuk hanya menyalin file .frm dan .ibd, anda sejalan dengan dunia yang menyakitkan. menyalin file .frm dan .ibd dari tabel innodb hanya baik <strong> <em> jika dan hanya jika anda dapat menjamin bahwa id tablespace dari file .ibd cocok persis dengan entri tablespace id di metadata dari file ibdata1</em> </strong>.</p><p>saya menulis dua posting di dba stackexchange tentang konsep id tablespace ini</p><ul> <li> <a href="https://dba.stackexchange.com/questions/9500/table-compression-in-innodb/9555#9555">kompresi tabel dalam innodb?</a> (di bawah judul 'memulihkan database')</li> <li> <a href="https://dba.stackexchange.com/questions/6268/how-to-recover-an-innodb-table-whose-files-were-moved-around/6269#6269">cara memulihkan tabel innodb yang file-nya dipindahkan</a> </li> </ul><p>berikut ini adalah tautan yang sangat baik tentang cara memasang kembali file .ibd ke ibdata1 jika id tablespace tidak cocok: <a href="http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file">http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in- file</a> . setelah membaca ini, anda harus segera menyadari bahwa menyalin file .ibd benar-benar gila.</p><p>untuk innodb, anda hanya perlu memindahkan sesuatu ini</p><pre><code>create table db2.mytable like db1.mytable; insert into db2.mytable select * from db1.mytable; </code></pre><p>untuk membuat salinan tabel innodb.</p><p>jika anda memigrasikannya ke server db lain, gunakan mysqldump.</p><p>sehubungan dengan mencampur semua tabel innodb dari semua database, saya benar-benar dapat melihat kebijaksanaan dalam melakukannya. di perusahaan hosting db/web perusahaan saya, saya memiliki satu klien mysql yang memiliki tabel di satu basis data yang batasannya dipetakan ke tabel lain di basis data lain dalam instance mysql yang sama. dengan satu repositori metadata yang umum, itu membuat dukungan transaksional dan pengoperasian mvcc mungkin di beberapa basis data.</p> <p>pendekatan yang paling banyak digunakan yang pernah saya lihat adalah menggunakan ellipsis untuk menunjukkan bahwa ada lebih banyak teks, seperti ini:</p><p><img src="https://i.stack.imgur.com/o0usc.png" alt="alt text"></p><p>anda kemudian dapat memberikan tooltip saat mengarahkan kursor untuk menunjukkan nama lengkap kepada pengguna. pada mac os, apple mencoba untuk menyingkat teks sebagai langkah pertama. mereka melakukannya dengan mengurangi jarak antara huruf dan kata. idenya adalah untuk menunjukkan kepada anda sebanyak mungkin karakter sebelum menambahkan ellipsis sebagai pilihan terakhir.</p><p>saya telah melihat pendekatan lain yang jauh lebih elegan dalam aplikasi di suatu tempat di mana mereka memudar huruf terakhir yang dapat ditampilkan. saya tidak dapat mengingat nama aplikasi, tetapi tampilannya seperti ini:</p><p><img src="https://i.stack.imgur.com/lc3jv.png" alt="alt text"></p><p>ini jelas lebih banyak pekerjaan, tetapi jelas terlihat lebih modern dan berkelas. saya terkejut bahwa ini belum menjadi fitur standar mac os. omong-omong, apple <em>tidak</em> menggunakan fading di spotlight untuk menunjukkan kepada anda path file yang panjang:</p><p><img src="https://i.stack.imgur.com/cr1nu.png" alt="alt text"></p><p>selain path file yang pudar, lihat file "yllistenerbase.cpp": anda dapat melihat bahwa file itu terkondensasi jika anda membandingkannya dengan file .h-nya. jalur file dengan efek fading ada di bagian bawah jendela.</p> <p>tidak, redis lebih dari sekadar cache. </p><p>seperti cache, redis menyimpan kunci = pasangan nilai. tetapi tidak seperti cache, redis memungkinkan anda beroperasi pada nilai-nilai. ada 5 tipe data dalam redis - string, set, hash, daftar dan set diurutkan. setiap tipe data memperlihatkan berbagai operasi.</p><p>cara terbaik untuk memahami redis adalah dengan memodelkan suatu aplikasi tanpa memikirkan bagaimana anda akan menyimpannya dalam database. </p><p>katakanlah kita ingin membangun stackoverflow.com. untuk membuatnya sederhana, kita membutuhkan pertanyaan, jawaban, tag, dan pengguna.</p><h2>pertanyaan modeling, pengguna dan jawaban</h2><p>setiap objek dapat dimodelkan sebagai peta. misalnya, pertanyaan adalah peta dengan bidang {id, judul, date\_asked, suara, asked\_by, status}. demikian pula, sebuah jawaban adalah peta dengan bidang {id, question\_id, answer\_text, answer\_by, suara, status}. demikian pula, kita dapat memodelkan objek pengguna.</p><p>masing-masing benda ini dapat langsung disimpan di redis sebagai hash. untuk menghasilkan id unik, anda dapat menggunakan perintah kenaikan atom. sesuatu seperti ini - </p><pre><code>$ hincrby unique\_ids question 1 (integer) 1 $ hmset question:1 title "is redis just a cache?" asked\_by 12 votes 0 ok $ hincrby unique\_ids answer 1 (integer) 1 $ hmset answer:1 question\_id 1 answer\_text "no, its a lot more" answered\_by 15 votes 1 ok </code></pre><h2>menangani suara</h2><p>sekarang, setiap kali seseorang menjawab pertanyaan atau jawaban, anda hanya perlu melakukan ini </p><pre><code>$ hincrby question:1 votes 1 (integer) 1 $ hincrby question:1 votes 1 (integer) 2 </code></pre><h2>daftar pertanyaan untuk beranda</h2><p>selanjutnya, kami ingin menyimpan pertanyaan terbaru untuk ditampilkan di beranda. jika anda sedang menulis program .net atau java, anda akan menyimpan pertanyaan dalam daftar. ternyata, itu adalah cara terbaik untuk menyimpan ini di redis juga. </p><p>setiap kali seseorang mengajukan pertanyaan, kami menambahkan idnya ke daftar. </p><pre><code>$ lpush questions question:1 (integer) 1 $ lpush questions question:2 (integer) 1 </code></pre><p>sekarang, ketika anda ingin merender beranda, anda meminta redis untuk 25 pertanyaan terbaru. </p><pre><code>$ lrange questions 0 24 1) "question:100" 2) "question:99" 3) "question:98" 4) "question:97" 5) "question:96" ... 25) "question:76" </code></pre><p>sekarang setelah anda memiliki id, ambil item dari redis menggunakan pipelining dan menunjukkannya kepada pengguna.</p><h2>pertanyaan dengan tag, diurut berdasarkan pilihan</h2><p>selanjutnya, kami ingin mengambil pertanyaan untuk setiap tag. tetapi so memungkinkan anda untuk melihat pertanyaan pilihan teratas, pertanyaan baru atau pertanyaan yang tidak dijawab di bawah setiap tag.</p><p>untuk memodelkan ini, kami menggunakan fitur set diurutkan redis. set diurutkan memungkinkan anda untuk mengaitkan skor dengan setiap elemen. anda kemudian dapat mengambil elemen berdasarkan skor mereka. </p><p>ayo maju dan lakukan ini untuk tag redis </p><pre><code>$ zadd questions\_by\_votes\_tagged:redis 2 question:1 (integer) 1 $ zadd questions\_by\_votes\_tagged:redis 10 question:2 (integer) 1 $ zadd questions\_by\_votes\_tagged:redis 5 question:613 (integer) 1 $ zrange questions\_by\_votes\_tagged:redis 0 5 1) "question:1" 2) "question:613" 3) "question:2" $ zrevrange questions\_by\_votes\_tagged:redis 0 5 1) "question:2" 2) "question:613" 3) "question:1" </code></pre><p>apa yang kita lakukan di sini? kami menambahkan pertanyaan ke set yang diurutkan, dan mengaitkan skor (jumlah suara) untuk setiap pertanyaan. setiap kali sebuah pertanyaan dibatalkan, kami akan menambah nilainya. dan ketika pengguna mengklik &quot;pertanyaan yang ditandai redis, disortir berdasarkan suara&quot;, kami hanya melakukan <code>zrevrange</code> dan mendapatkan kembali pertanyaan teratas.</p><h2>pertanyaan waktu nyata tanpa halaman yang menyegarkan</h2><p>dan akhirnya, fitur bonus. jika anda membiarkan halaman pertanyaan terbuka, so akan memberi tahu anda ketika pertanyaan baru ditambahkan. bagaimana redis bisa membantu di sini?</p><p>redis memiliki model pub-sub. anda dapat membuat saluran, misalnya &quot;channel\_questions\_tagged\_redis&quot;. anda kemudian <code>subscribe</code> pengguna ke saluran tertentu. ketika pertanyaan baru ditambahkan, anda akan <code>publish</code> pesan ke saluran itu. semua pengguna akan mendapatkan pesan. anda harus menggunakan teknologi web seperti soket atau komet web untuk benar-benar mengirimkan pesan ke browser, tetapi redis membantu anda dengan semua pipa ledeng di sisi server.</p><h2>kegigihan, keandalan, dll.</h2><p>tidak seperti cache, redis tetap menyimpan data pada hard disk. anda dapat memiliki pengaturan master-slave untuk memberikan keandalan yang lebih baik. untuk mempelajari lebih lanjut, buka topik kegigihan dan replikasi di sini - <a href="http://redis.io/documentation">http://redis.io/documentation</a> </p> <p>semuanya sesuai dengan standar ansi:</p><p> <a href="http://support.microsoft.com/kb/316626">trailing blank menjelaskan</a> :</p><blockquote> <p>sql server mengikuti spesifikasi ansi/iso sql-92 (bagian 8.2, aturan umum # 3) tentang cara membandingkan string dengan spasi. standar ansi membutuhkan padding untuk string karakter yang digunakan dalam perbandingan sehingga panjangnya cocok sebelum membandingkannya. padding secara langsung mempengaruhi semantik predikat klausa where dan having dan perbandingan string transact-sql lainnya. sebagai contoh, transact-sql menganggap string 'abc' dan 'abc' setara untuk sebagian besar operasi perbandingan.</p> <p>satu-satunya pengecualian untuk aturan ini adalah predikat like. ketika sisi kanan dari ekspresi predikat like fitur nilai dengan spasi tambahan, sql server tidak memadatkan dua nilai dengan panjang yang sama sebelum perbandingan terjadi. karena tujuan dari predikat like, menurut definisi, adalah untuk memfasilitasi pencarian pola daripada tes persamaan string sederhana, ini tidak melanggar bagian dari spesifikasi ansi sql-92 yang disebutkan sebelumnya.</p> </blockquote><p>berikut adalah contoh umum dari semua kasus yang disebutkan di atas:</p><pre><code>declare @a varchar(10) declare @b varchar(10) set @a = '1' set @b = '1 ' --with trailing blank select 1 where @a = @b and @a not like @b and @b like @a </code></pre><p>inilah beberapa detail lebih lanjut tentang <a href="http://msdn.microsoft.com/en-us/library/ms179859.aspx">mengeklik kosong dan klausa <code>like</code></a> .</p><p><strong> [~ # ~] tetapi [~ # ~] </strong> jika anda ingin membuatnya berbeda - anda dapat memutuskan untuk menggunakan fungsi <code>datalength</code> alih-alih <code>len</code>, karena</p><pre><code>select 1 where len('john ') = len('john') </code></pre><p>akan menempatkan anda 1 sebagai gantinya</p><pre><code>select 1 where datalength('john ') = datalength('john') </code></pre><p><strong> solusinya </strong> adalah</p><ul> <li>untuk menggunakan fungsi datalength untuk membedakan antara string</li> <li>untuk memasukkan string ke dalam tipe nvarchar - mungkin lebih baik menyatakan tipe ini ke parameter sp</li> </ul> <p>ini telah ditanyakan dalam stack overflow <a href="https://stackoverflow.com/questions/404040/how-do-you-like-your-primary-keys/404057#404057">di sini</a> dan <a href="https://stackoverflow.com/questions/829284/guid-vs-int-identity">di sini</a> .</p><p> <a href="http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html">posting jeff</a> menjelaskan banyak tentang pro dan kontra menggunakan guid.</p><blockquote> <h3>guid pro</h3> <ul> <li>unik di setiap tabel, setiap basis data, dan setiap server</li> <li>mengizinkan penggabungan catatan dengan mudah dari database yang berbeda</li> <li>mengizinkan distribusi basis data dengan mudah di beberapa server</li> <li>anda dapat membuat id di mana saja, alih-alih harus bolak-balik ke database</li> <li>sebagian besar skenario replikasi membutuhkan guid kolom pula</li> </ul> <h3>kontra guid</h3> <ul> <li>ini adalah kekalahan 4 kali lebih besar dari nilai indeks 4 byte tradisional; ini dapat memiliki implikasi kinerja dan penyimpanan yang serius jika anda tidak berhati-hati</li> <li>tidak praktis untuk debug (<code>where userid='{bae7df4-ddf-3rg-5ty3e3rf456as10}'</code>)</li> <li>guid yang dihasilkan sebagian harus berurutan untuk kinerja terbaik (misalnya, <code>newsequentialid()</code> pada sql server 2005+) dan untuk memungkinkan penggunaan indeks berkerumun</li> </ul> </blockquote><p>jika anda yakin tentang kinerja dan anda tidak berencana untuk mereplikasi atau menggabungkan catatan, maka gunakan <code>int</code>, dan atur secara otomatis peningkatan (<em> identitas benih di sql server </em>).</p> <p>rencana yang anda miliki saat ini terlihat seperti rencana paling optimal bagi saya.</p><p>saya tidak setuju dengan pernyataan di jawaban lain bahwa ia mengirim baris 2.6m ke server jarak jauh.</p><p>rencana itu terlihat bagi saya seolah-olah untuk masing-masing 54 baris yang dikembalikan dari permintaan jarak jauh itu melakukan pencarian indeks ke tabel lokal anda untuk menentukan apakah cocok atau tidak. ini adalah rencana optimal.</p><p>mengganti dengan hash join atau gabung bergabung akan menjadi kontraproduktif mengingat ukuran tabel dan menambahkan perantara <code>#temp</code> table hanya menambahkan langkah tambahan yang sepertinya tidak memberi anda keuntungan.</p> Upload File kotak adalah di mana kita're saat ini jika anda don't ingin melibatkan teknologi lainnya seperti Flash, Java atau ActiveX.


Dengan HTML anda cukup banyak terbatas pada pengalaman anda've dijelaskan (tidak ada progress bar, double menyampaikan, dll). Jika anda bersedia untuk menggunakan beberapa javascript, anda dapat memecahkan beberapa masalah dengan memberikan umpan balik yang upload sedang berlangsung dan bahkan [menunjukkan kemajuan upload](http://www.raditha.com/php/progress.php) (ini adalah hack karena anda tidak't harus melakukan full round-trip ke server dan kembali, tapi setidaknya ia bekerja).


Jika anda bersedia untuk menggunakan Flash (yang tersedia cukup banyak di mana saja dan pada banyak platform), anda dapat mengatasi hampir semua masalah ini. Cepat googling muncul [dua](http://www.downloadsquad.com/2006/11/16/swfupload-open-source-flash-multi-file-upload/) [seperti](http://www.codeproject.com/KB/aspnet/FlashUpload.aspx) komponen, keduanya gratis *dan* open source. Saya tidak pernah menggunakan salah satu dari mereka, tapi mereka terlihat baik. BTW, Flash isn't tanpa masalah yang baik, misalnya ketika menggunakan multi-file uploader untuk slide share, browser yang terus-menerus menerjang pada saya :-(


Mungkin solusi terbaik saat ini adalah untuk mendeteksi secara dinamis jika pengguna memiliki Flash, dan jika itu's kasus, memberikan versi flash uploader, sementara masih membuat itu mungkin untuk memilih HTML dasar satu.


HTH kata kunci merupakan sebuah kata atau konsep dengan keistimewaan, yang berarti kata apapun yang digunakan sebagai kunci dan kode untuk menghubungkan ke kata lain atau informasi lain. kata kunci pada blog terbagi menjadi dua yaitu:
 


 kata kunci pendek, yaitu kata kunci yang hanya terdiri dari maksimal dua suku kata.
 kata kunci panjang, yaitu kata kunci yang lebih dari dua suku kata.



dengan demikian, kata kunci hendaknya terdiri dari dua suku kata atau lebih dari dua suku kata.